【问题标题】:Sort pandas multi-index by count?按计数对熊猫多索引进行排序?
【发布时间】:2016-05-10 04:50:00
【问题描述】:

我有一个由多索引操作生成的数据框,如下所示。

                      Col3
Col1        Col2
A              A1         N
B              B1         N
               B2         N
C              C1         N
               C2         N
               C3         N 

我正在尝试按级别 A、B 和 C 的行数降序计数对这个数据框进行排序。在这种情况下,级别 A 有 1 行,B 有 2 行,C有 3 行...所以输出将是

                      Col3
Col1        Col2
C              C1         N
               C2         N
               C3         N
B              B1         N
               B2         N
A              A1         N 

我可以考虑通过实际计算每个级别的行数并在 df 中添加一列进行排序来手动执行此操作,但是有更优雅的方法吗?如果是这样,有没有办法推广到更多级别?

谢谢!

编辑:生成原始数据框的代码。

df = pd.DataFrame([['a', 'z', 'x', 0.123], ['a','z', 'x', 0.234],
                ['a', 'z', 'y', 0.451], ['b', 'z', 'x', 0.453], ['b', 'z', 'x', 0.453], ['b', 'z', 'x', 0.453], ['b', 'z', 'x', 0.453]],
               columns=['first', 'second', 'value1', 'value2']
               ).set_index(['first', 'second'])

运行df.ix[df.groupby(level=0).size().sort_values(ascending=False).index,:] 产生TypeError: Expected tuple, got str

【问题讨论】:

    标签: python sorting pandas


    【解决方案1】:

    IIUC 你可以通过groupby 在第一个索引级别上进行操作,然后对size 进行排序并使用它来重新索引到你的df:

    In [25]:
    df.ix[df.groupby(level=0).size().sort_values(ascending=False).index,:]
    
    Out[25]:
              Col3
    Col1 Col2     
    C    C1      N
         C2      N
         C3      N
    B    B1      N
         B2      N
    A    A1      N
    

    分解以上内容:

    In [26]:
    df.groupby(level=0).size()
    
    Out[26]:
    Col1
    A    1
    B    2
    C    3
    dtype: int64
    
    In [27]:
    df.groupby(level=0).size().sort_values(ascending=False)
    
    Out[27]:
    Col1
    C    3
    B    2
    A    1
    dtype: int64
    
    In [28]:
    df.groupby(level=0).size().sort_values(ascending=False).index
    
    Out[28]:
    Index(['C', 'B', 'A'], dtype='object', name='Col1')
    

    编辑

    好的,这比我预期的要复杂,但以下工作:

    In [76]:
    i = df.index.get_level_values(0)
    df.iloc[i.reindex(df.groupby(level=0).size().sort_values(ascending=False).index)[1]]
    
    Out[76]:
                 value1  value2
    first second               
    b     z           x   0.453
          z           x   0.453
          z           x   0.453
          z           x   0.453
    a     z           x   0.123
          z           x   0.234
          z           y   0.451
    

    所以这样做是获取第一级索引值,然后 reindexes 将它们与 groupby 结果进行对比,并使用针对原始 df 生成的 int 索引

    【讨论】:

    • 当我运行你建议的方法时,我得到TypeError: Expected tuple, got str。 df.groupby(level=0).size().sort_values(ascending=False).index 生成具有正确值的 Index 对象,但实际索引失败。有什么想法吗?
    • 你用的是什么版本的熊猫?我正在运行 0.18.0,这工作正常
    • 我正在使用熊猫:0.18.1。
    • 你能发布原始数据和代码,我可以运行这些代码来尝试重新创建错误,谢谢
    • 抱歉....我的原始数据框有多个索引列。生成它的代码在上面的原始问题中。
    猜你喜欢
    • 2013-10-09
    • 2017-01-12
    • 1970-01-01
    • 2014-05-24
    • 2019-04-12
    • 1970-01-01
    • 2017-10-12
    • 2019-06-29
    • 2020-10-20
    相关资源
    最近更新 更多