我有一个DataFrame (多个每日时间序列),DateTimeIndex作为index,MultiIndex作为columns。我想选择一个列并创建一个按年分组数据的Box图。我认为这很容易,但我正在努力取得一些结果。
>>> daily.shape
(11319, 118)
>>> daily.index
DatetimeIndex(['1986-01-01', '1986-01-02', '1986-01-03', '1986-01-04',
'1986-01-05', '1986-01-06', '1986-01-07', '1986-01-08',
'1986-01-09', '1986-01-10',
...
'2016-12-22', '2016-12-23', '2016-12-24', '2016-12-25',
'2016-12-26', '2016-12-27', '2016-12-28', '2016-12-29',
'2016-12-30', '2016-12-31'],
dtype='datetime64[ns]', name='timevalue', length=11319, freq=None)
>>> daily.columns
MultiIndex(levels=[['41B001', '41B004', '41B006', '41B008', '41B011', '41MEU1', '41N043', '41R001', '41R002', '41R012', '41WOL1', '41WOL2', '47E013', 'T1M001', 'T1M003'], ['BA-10.0', 'BA-2.5', 'BC', 'CO', 'CO2', 'NO', 'NO2', 'NOx', 'O3', 'PM-10.0', 'PM-2.5', 'RH', 'SO2', 'T', 'UVPM', 'VO-10.0', 'VO-2.5', 'WD', 'WS-s', 'WS-v', 'p']],
labels=[[0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14], [5, 6, 7, 3, 5, 6, 7, 8, 3, 5, 6, 7, 8, 3, 5, 6, 7, 12, 0, 1, 5, 6, 7, 8, 9, 10, 15, 16, 0, 1, 5, 6, 7, 9, 10, 15, 16, 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 2, 3, 4, 5, 6, 7, 12, 14, 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 0, 2, 3, 4, 5, 6, 7, 8, 9, 12, 14, 15, 4, 5, 6, 7, 12, 11, 13, 13, 17, 18, 19, 20, 11, 13, 13, 17, 18, 19, 20]],
names=['sitekey', 'measurandkey'])我所能做到的就是:
fig, axe = plt.subplots()
daily.loc[:,[('41R001', 'SO2')]].groupby(daily.index.map(lambda x: x.year)).boxplot(ax=axe, subplots=False, rot=90)但这将需要其他后处理的标签轴。
当我尝试reset_index()应用函数和使用pivot()时,由于MultiIndex的原因,出现了索引错误。
d = daily.reset_index()
d['timevalue']例外是:不能处理一个非唯一的多索引!这一点我不明白,因为在我的MultiIndex中没有出现过MultiIndex。我也尝试过.loc[],但我认为问题在其他地方。
所以,我要做的很简单:
loc和一个组合键,如上面的例子),并得到一个按年分组数据的时间盒图。我认为这可能很容易,但是由于mutli索引错误,我不能在这个DataFrame中正确地使用DataFrame。
发布于 2017-03-28 11:54:19
如果您不介意使用seaborn库,您可以非常轻松地绘制这个图:
import pandas as pd
import seaborn as sns
index = pd.DatetimeIndex(start=pd.to_datetime('1985-01-01'),
end = pd.to_datetime('2017-03-08'),
freq='d')
df = pd.DataFrame(index = index,
data = np.random.uniform(-1,1,size=(index.shape[0],4)),
columns=pd.MultiIndex.from_arrays([['A','A','B','B'],
['d','e','d','e']]))
df['Year'] = df.index.year
# A B Year
# d e d e
# 1985-01-01 0.205208 -0.228484 0.296273 0.545031 1985
# 1985-01-02 0.546436 -0.538920 0.173388 0.848590 1985
# 1985-01-03 -0.367593 -0.974911 -0.796331 -0.946239 1985
# 1985-01-04 -0.346102 -0.951542 -0.975172 0.951099 1985
# 1985-01-05 0.973975 0.708254 -0.150454 0.145298 1985
ax = sns.boxplot(data = df, x='Year',y=('A','e'))
for item in ax.get_xticklabels():
item.set_rotation(90)由此产生的图像:

我试过使用pandas.DataFrame.boxplot()方法,但在很短的时间内无法使它在这种情况下工作。
发布于 2017-03-28 12:26:21
使用groupby和pivot,你走在正确的轨道上。首先,让我们创建一些虚拟数据:
# create index
index = pd.DatetimeIndex(pd.date_range("1986-01-01", periods=200, freq="w"))
# create columns
col_lvl_1 = ['41B001', '41B004', '41B006']
col_lvl_2 = ['BA-10.0', 'BA-2.5', 'BC']
columns = pd.MultiIndex.from_product([col_lvl_1, col_lvl_2], names=["Lvl1", "Lvl2"])
# random data
data = np.random.randint(0, 100, size=(200, 9))
# create df
df = pd.DataFrame(data, index=index, columns=columns)
df["year"] = df.index.year
print(df.head())
Lvl1 41B001 41B004 41B006 year
Lvl2 BA-10.0 BA-2.5 BC BA-10.0 BA-2.5 BC BA-10.0 BA-2.5 BC
1986-01-05 81 41 52 87 73 41 14 20 66 1986
1986-01-12 14 27 33 96 69 85 93 28 45 1986
1986-01-19 31 46 87 88 19 62 89 50 1 1986
1986-01-26 21 6 45 2 73 64 71 42 38 1986
1986-02-02 76 94 33 64 33 56 91 43 42 1986现在,你可以
就这样。
for column in df.columns.values[:-1]:
sub_df = df.loc[:, [column, ("year", "")]]
pivot_df = sub_df.pivot(columns="year")
pivot_df.columns = pivot_df.columns.levels[2]
pivot_df.plot(kind="box", title=column)


后面还有更多的照片..。
https://stackoverflow.com/questions/43065157
复制相似问题