【问题标题】:Sort a 2 index pivot table: values within group, index based on values对 2 索引数据透视表进行排序:组内的值,基于值的索引
【发布时间】:2018-06-07 15:33:18
【问题描述】:

我有一个这样的数据框:

x = pd.DataFrame({'col1':['bul', 'eng','eng', 'ger','ger', 'fra','fra'],
                  'col2':['fra', 'ger','fra', 'fra','eng', 'ger','eng'],
                  'col3':[    1,     4,    2,     6,    7,    20,    5]})
pt = pd.pivot_table(x, index = ['col1', 'col2'], values = 'col3', aggfunc = np.sum)
pt
           col3
col1 col2      
bul  fra      1
eng  fra      2
     ger      4
fra  eng      5
     ger     20
ger  eng      7
     fra      6

我想要排序到达:

           col3
col1 col2      
fra  ger     20
     eng      5
ger  eng      7
     fra      6
eng  ger      4
     fra      2
bul  fra      1

第三列按降序排序(在 col1 单元格内),col1 基于 col3 的属性排序,这里是 max (20 > 7 > 4 > 1)

有几个问题涉及类似的问题,我的问题是相关的,因为它具有描述性标题和示例数据(其他问题的答案也不适合我)

https://stackoverflow.com/a/45300480/3014199 建议

df = pt.reset_index()
       .sort_values(['col1','col3'], ascending=[True, False])
       .set_index(['col1','col2'])

print(df)
           col3
col1 col2      
bul  fra      1
eng  fra      2
     ger      4
fra  eng      5
ger  fra      6
     eng      7
fra  ger     20

这似乎为那里的 dataFrame 排序 col3,但似乎对我的数据根本不起作用。

Pandas: Sort pivot table 似乎也很有希望,但和其他人一样,我得到了ValueError: all keys need to be the same shape

更新:
我的例子不够笼统,对不起!如果 2 个组共享相同的最大值,它也应该工作,例如

x2 = pd.DataFrame({'col1':['bul', 'eng','eng', 'ger','ger', 'fra','fra'],
                   'col2':['fra', 'ger','fra', 'fra','eng', 'ger','eng'],
                   'col3':[    1,     7,    2,     6,    7,    20,    5]})

例如MaxU 的解决方案产生:

           col3
col1 col2           
fra  ger   20 
     eng   5  
ger  eng   7  
eng  ger   7  
ger  fra   6  
eng  fra   2  
bul  fra   1  

我敢打赌,将 col1 的散列(或者更确切地说是一个分组数除以 10)添加到“最大值”会起作用,但必须有更好的方法...
是的!这似乎有效:

pt['New']=pt.groupby(level='col1').col3.transform('max')
pt['New'] = 1/(pt.index.labels[0]+1)+pt['New'].values
pt=pt.sort_values(['New','col3'],ascending=False).drop('New',1)

【问题讨论】:

    标签: pandas sorting pivot-table


    【解决方案1】:

    我们可以使用一个新的para来实现这个

    pt['New']=pt.groupby(level='col1').col3.transform('max')
    pt=pt.sort_values(['New','col3'],ascending=False).drop('New',1)
    pt
    Out[1445]: 
               col3
    col1 col2      
    fra  ger     20
         eng      5
    ger  eng      7
         fra      6
    eng  ger      4
         fra      2
    bul  fra      1
    

    更新:

    pt['New']=pt.groupby(level='col1').col3.transform('max')
    pt['New1']=pt.groupby(level='col1').col3.ngroup()
    pt=pt.sort_values(['New','New1','col3'],ascending=False)
    
    
    pt
    Out[151]: 
               col3  New  New1
    col1 col2                 
    fra  ger     20   20     2
         eng      5   20     2
    ger  eng      7    7     3
         fra      6    7     3
    eng  ger      7    7     1
         fra      2    7     1
    bul  fra      1    1     0
    

    【讨论】:

    • 我只是在不同的数据上尝试过这个(将 4 替换为 7),如果 2 个组的最大值相等,它就不起作用。请参阅我的问题的附录。
    • 等等!在 sort_values 我们仍然需要 'col3' -> sort_values(['New','New1','col3']...
    【解决方案2】:

    这是一个与 Wen 非常相似的解决方案,它使用 set_indexsort_indexreset_index

    In [188]: (pt.set_index([pt.groupby(level='col1').col3.transform('max'), pt['col3']], append=True)
         ...:    .sort_index(level=[2,3], ascending=False)
         ...:    .reset_index(level=[2,3], drop=True)
         ...: )
         ...:
    Out[188]:
               col3
    col1 col2
    fra  ger     20
         eng      5
    ger  eng      7
         fra      6
    eng  ger      4
         fra      2
    bul  fra      1
    

    【讨论】:

    • 这还不是我需要的,col3 应该下降,但这里 5 超过 20,7 超过 6。我试图摆弄ascending,但我无法自己修复
    • 您还需要注意:您的解决方案假定最大值都是唯一的,但不一定。查看我的问题的更新
    猜你喜欢
    • 2023-03-29
    • 1970-01-01
    • 2013-02-11
    • 2011-08-03
    • 2016-12-27
    • 2017-12-31
    • 2017-04-14
    • 2016-09-15
    相关资源
    最近更新 更多