【问题标题】:pandas MultiIndex on columns select columns from level 0 (outside) as well as level 1 (inside)列上的 pandas MultiIndex 从级别 0(外部)和级别 1(内部)中选择列
【发布时间】:2020-08-19 19:13:32
【问题描述】:

使用以下虚拟数据框:

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()

即我希望能够选择df[['dt', 'group', ('bar', '25%'), , ('bar', '25%'), , ('bar', '25%')]]

如何执行这种多级选择?

我的最终目标是能够绘制每个类别随时间变化的百分位数,其中每个类别描述一种颜色:

import seaborn as sns; sns.set()
sns.lineplot(data=df.reset_index()['baz'][['25%', '50%', '75%']], hue='group')

但是,在剩余的数据框中,没有留下任何关于组的信息。

【问题讨论】:

  • 类似df["bar"].filter(like="%")?
  • @HenryYik 的建议非常简洁......我认为你应该将其发布为答案

标签: python pandas seaborn multi-index percentile


【解决方案1】:

不确定这是不是你想要的:

 #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

【讨论】:

    【解决方案2】:

    另一种给猫剥皮的方法:

    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
    

    【讨论】:

      【解决方案3】:

      即我希望能够选择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')
      

      【讨论】:

      • 虽然这只能绘制一条线,即 25,而不是 50 或 75。
      猜你喜欢
      • 1970-01-01
      • 2021-01-25
      • 1970-01-01
      • 2022-01-04
      • 2019-10-18
      • 2022-06-15
      • 2018-06-24
      • 2019-01-26
      相关资源
      最近更新 更多