pandas 列的 MultiIndex select 级别 0(外部)和级别 1(内部)的列
pandas MultiIndex on columns select columns from level 0 (outside) as well as level 1 (inside)
使用虚拟数据帧:
import pandas as pd
df = pd.DataFrame({'dt':['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-03', '2020-01-01', '2020-01-02', '2020-01-03', '2020-01-03'], 'group':['a', 'a', 'b', 'b', 'a', 'a', 'b', 'b'], 'bar':[1,2,3, 4, 1,2,3, 4], 'baz':[3,4,5, 6, 3,4,5, 6]})
df = df.groupby(['dt', 'group']).describe()
即我希望能够selectdf[['dt', 'group', ('bar', '25%'), , ('bar', '25%'), , ('bar', '25%')]]
。
如何执行此多级 select离子?
我的最终目标是能够绘制每个类别随时间变化的百分位数,其中每个类别描述一种颜色:
import seaborn as sns; sns.set()
sns.lineplot(data=df.reset_index()['baz'][['25%', '50%', '75%']], hue='group')
但是,在剩余的数据框中,没有留下任何关于组的信息。
I.e. I want to be able to select df[['dt', 'group', ('bar', '25%'), , ('bar', '25%'), , ('bar', '25%')]]
.
您可以执行以下操作:
df.reset_index()[[('dt', ""), ('group', ""), ('bar', '25%'), ('bar', '50%')]]
输出:
dt group bar
25% 50%
0 2020-01-01 a 1.0 1.0
1 2020-01-02 a 2.0 2.0
2 2020-01-03 b 3.0 3.5
至于图表,在我看来你正在尝试绘制一个具有 4 个维度的图...(x->dt,y->dataframe 值,hue-> 对应于每个组,然后你有每个百分位列,例如 ('bar', '25%')
、('bar', '50%')
)。目前尚不清楚您要如何区分情节中的 ('bar', '25%')
和 ('bar', '50%')
。也许您期待 6 个单独的图(3 个百分位数 * 2 列 [bar, baz]),在这种情况下这可能会有所帮助:
sns.lineplot(data=df.reset_index(), x="dt", y=("bar", '25%'), hue='group')
不确定这是否是您想要的:
#assigned outcome to a different variable
res = df.groupby(['dt', 'group']).describe()
#create a slicer, makes it easier to slice the multiIndex
idx = pd.IndexSlice
res.loc[idx[:],idx['bar',['25%','50%','75%']]]
您可以使用它来获得相同的结果
res.loc(axis=1)['bar',['25%','50%','75%']]
bar
25% 50% 75%
dt group
2020-01-01 a 1.0 1.0 1.0
2020-01-02 a 2.0 2.0 2.0
2020-01-03 b 3.0 3.5 4.0
或横截面切片:
res.xs('bar',level=0,axis=1).filter(['25%','50%','75%'])
25% 50% 75%
dt group
2020-01-01 a 1.0 1.0 1.0
2020-01-02 a 2.0 2.0 2.0
2020-01-03 b 3.0 3.5 4.0
另一种剥猫皮的方法:
print (df["bar"].filter(like="%"))
25% 50% 75%
dt group
2020-01-01 a 1.0 1.0 1.0
2020-01-02 a 2.0 2.0 2.0
2020-01-03 b 3.0 3.5 4.0
使用虚拟数据帧:
import pandas as pd
df = pd.DataFrame({'dt':['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-03', '2020-01-01', '2020-01-02', '2020-01-03', '2020-01-03'], 'group':['a', 'a', 'b', 'b', 'a', 'a', 'b', 'b'], 'bar':[1,2,3, 4, 1,2,3, 4], 'baz':[3,4,5, 6, 3,4,5, 6]})
df = df.groupby(['dt', 'group']).describe()
即我希望能够selectdf[['dt', 'group', ('bar', '25%'), , ('bar', '25%'), , ('bar', '25%')]]
。
如何执行此多级 select离子?
我的最终目标是能够绘制每个类别随时间变化的百分位数,其中每个类别描述一种颜色:
import seaborn as sns; sns.set()
sns.lineplot(data=df.reset_index()['baz'][['25%', '50%', '75%']], hue='group')
但是,在剩余的数据框中,没有留下任何关于组的信息。
I.e. I want to be able to select
df[['dt', 'group', ('bar', '25%'), , ('bar', '25%'), , ('bar', '25%')]]
.
您可以执行以下操作:
df.reset_index()[[('dt', ""), ('group', ""), ('bar', '25%'), ('bar', '50%')]]
输出:
dt group bar
25% 50%
0 2020-01-01 a 1.0 1.0
1 2020-01-02 a 2.0 2.0
2 2020-01-03 b 3.0 3.5
至于图表,在我看来你正在尝试绘制一个具有 4 个维度的图...(x->dt,y->dataframe 值,hue-> 对应于每个组,然后你有每个百分位列,例如 ('bar', '25%')
、('bar', '50%')
)。目前尚不清楚您要如何区分情节中的 ('bar', '25%')
和 ('bar', '50%')
。也许您期待 6 个单独的图(3 个百分位数 * 2 列 [bar, baz]),在这种情况下这可能会有所帮助:
sns.lineplot(data=df.reset_index(), x="dt", y=("bar", '25%'), hue='group')
不确定这是否是您想要的:
#assigned outcome to a different variable
res = df.groupby(['dt', 'group']).describe()
#create a slicer, makes it easier to slice the multiIndex
idx = pd.IndexSlice
res.loc[idx[:],idx['bar',['25%','50%','75%']]]
您可以使用它来获得相同的结果
res.loc(axis=1)['bar',['25%','50%','75%']]
bar
25% 50% 75%
dt group
2020-01-01 a 1.0 1.0 1.0
2020-01-02 a 2.0 2.0 2.0
2020-01-03 b 3.0 3.5 4.0
或横截面切片:
res.xs('bar',level=0,axis=1).filter(['25%','50%','75%'])
25% 50% 75%
dt group
2020-01-01 a 1.0 1.0 1.0
2020-01-02 a 2.0 2.0 2.0
2020-01-03 b 3.0 3.5 4.0
另一种剥猫皮的方法:
print (df["bar"].filter(like="%"))
25% 50% 75%
dt group
2020-01-01 a 1.0 1.0 1.0
2020-01-02 a 2.0 2.0 2.0
2020-01-03 b 3.0 3.5 4.0