Pandas:基于其他多级列对最内层列进行分组排序

3

考虑以下数据框:

In [3771]: df = pd.DataFrame({'A': ['a'] * 11,
               'B': ['b'] * 11,
               'C': ['C1', 'C1', 'C2','C1', 'C3', 'C3', 'C2', 'C3', 'C3', 'C2', 'C2'],
               'D': ['D1', 'D2', 'D1', 'D3', 'D3', 'D2', 'D4', 'D4', 'D1', 'D2', 'D3'],
               'E': [{'value': '4', 'percentage': None}, {'value': 5, 'percentage': None}, {'value': 12, 'percentage': None}, {'value': 5, 'percentage': None}, {'value': '12', 'percentage': None}, {'value': 'N/A', 'percentage': None}, {}, {'value': 19, 'percentage': None}, {'value': 12, 'percentage': None}, {'value': 11, 'percentage': None}, np.nan],
               'F':[{'value': 72, 'percentage': None}, {'value': 72, 'percentage': None}, {'value': 66, 'percentage': None}, {'value': 62, 'percentage': None}, {'value': 66, 'percentage': None}, {'value': 16,      'percentage': None}, {'value': 67, 'percentage': None}, {'value': 67, 'percentage': None}, {'value': 66, 'percentage': None}, {'value': 54, 'percentage': None}, {'value': 78, 'percentage': None}]})

In [3779]: df
Out[3898]: 
    A  B   C   D                                     E                                  F
0   a  b  C1  D1    {'value': '4', 'percentage': None}  {'value': 72, 'percentage': None}
1   a  b  C1  D2      {'value': 5, 'percentage': None}  {'value': 72, 'percentage': None}
2   a  b  C2  D1     {'value': 12, 'percentage': None}  {'value': 66, 'percentage': None}
3   a  b  C1  D3      {'value': 5, 'percentage': None}  {'value': 62, 'percentage': None}
4   a  b  C3  D3   {'value': '12', 'percentage': None}  {'value': 66, 'percentage': None}
5   a  b  C3  D2  {'value': 'N/A', 'percentage': None}  {'value': 16, 'percentage': None}
6   a  b  C2  D4                                    {}  {'value': 67, 'percentage': None}
7   a  b  C3  D4     {'value': 19, 'percentage': None}  {'value': 67, 'percentage': None}
8   a  b  C3  D1     {'value': 12, 'percentage': None}  {'value': 66, 'percentage': None}
9   a  b  C2  D2     {'value': 11, 'percentage': None}  {'value': 54, 'percentage': None}
10  a  b  C2  D3                                   NaN  {'value': 78, 'percentage': None}

旋转 上述数据框:

In [3776]: x = df.pivot(['B', 'C', 'D'], 'A', ['E', 'F'])

In [3781]: x
Out[3900]: 
                                            E                                  F
A                                           a                                  a
B C  D                                                                          
b C1 D1    {'value': '4', 'percentage': None}  {'value': 72, 'percentage': None}
     D2      {'value': 5, 'percentage': None}  {'value': 72, 'percentage': None}
     D3      {'value': 5, 'percentage': None}  {'value': 62, 'percentage': None}
  C2 D1     {'value': 12, 'percentage': None}  {'value': 66, 'percentage': None}
     D2     {'value': 11, 'percentage': None}  {'value': 54, 'percentage': None}
     D3                                   NaN  {'value': 78, 'percentage': None}
     D4                                    {}  {'value': 67, 'percentage': None}
  C3 D1     {'value': 12, 'percentage': None}  {'value': 66, 'percentage': None}
     D2  {'value': 'N/A', 'percentage': None}  {'value': 16, 'percentage': None}
     D3   {'value': '12', 'percentage': None}  {'value': 66, 'percentage': None}
     D4     {'value': 19, 'percentage': None}  {'value': 67, 'percentage': None}

我希望对于每个外部列BC的组,按照多级索引(E, a)value键的值进行降序排列,以内部列D为基础进行排序。

编辑:

dict可以具有混合数据类型的value键。它可以是int、str、NaN或仅不可用。

预期输出:

                                            E                                  F
A                                           a                                  a
B C  D                                                                          
b C1 D2      {'value': 5, 'percentage': None}  {'value': 72, 'percentage': None}
     D3      {'value': 5, 'percentage': None}  {'value': 62, 'percentage': None}
     D1    {'value': '4', 'percentage': None}  {'value': 72, 'percentage': None}
  C2 D1     {'value': 12, 'percentage': None}  {'value': 66, 'percentage': None}
     D2     {'value': 11, 'percentage': None}  {'value': 54, 'percentage': None}
     D4                                    {}  {'value': 67, 'percentage': None}
     D3                                   NaN  {'value': 78, 'percentage': None}
  C3 D4     {'value': 19, 'percentage': None}  {'value': 67, 'percentage': None}
     D1     {'value': 12, 'percentage': None}  {'value': 66, 'percentage': None}
     D3   {'value': '12', 'percentage': None}  {'value': 66, 'percentage': None}
     D2  {'value': 'N/A', 'percentage': None}  {'value': 16, 'percentage': None}
 


 
1个回答

3
使用辅助的 MultiIndex 列,通过 Series.str.get 创建,然后使用DataFrame.sort_values 进行排序,最后移除辅助列的解决方案。
x[('new', 'a')] = pd.to_numeric(x[('E','a')].str.get('value'), errors='coerce')
lvl = x.index.names[:-1]

order = 'desc'

x = (x.sort_values(lvl + [('new', 'a')],ascending=[True] * len(lvl) + [order == 'asc'])
       .drop(('new', 'a'), axis=1))

print (x)

                                            E  \
A                                           a   
B C  D                                          
b C1 D2      {'value': 5, 'percentage': None}   
     D3      {'value': 5, 'percentage': None}   
     D1    {'value': '4', 'percentage': None}   
  C2 D1     {'value': 12, 'percentage': None}   
     D2     {'value': 11, 'percentage': None}   
     D3                                   NaN   
     D4                                    {}   
  C3 D4     {'value': 19, 'percentage': None}   
     D1     {'value': 12, 'percentage': None}   
     D3   {'value': '12', 'percentage': None}   
     D2  {'value': 'N/A', 'percentage': None}   

                                         F  
A                                        a  
B C  D                                      
b C1 D2  {'value': 72, 'percentage': None}  
     D3  {'value': 62, 'percentage': None}  
     D1  {'value': 72, 'percentage': None}  
  C2 D1  {'value': 66, 'percentage': None}  
     D2  {'value': 54, 'percentage': None}  
     D3  {'value': 78, 'percentage': None}  
     D4  {'value': 67, 'percentage': None}  
  C3 D4  {'value': 67, 'percentage': None}  
     D1  {'value': 66, 'percentage': None}  
     D3  {'value': 66, 'percentage': None}  
     D2  {'value': 16, 'percentage': None}  

1
@IoaTzimas - 可能有新功能,也可能有一些错误。 - jezrael
1
@jezrael,您能否将此解决方案更加通用化,以便我不必硬编码列名“B”、“C”和“D”?我总是需要对最内层的列进行排序,即“D”,而其余列(“B”和“C”)可以相同。 - Mayank Porwal
@jezrael 感谢您的帮助。还有一个情况,我需要添加示例数据吗? - Mayank Porwal
@MayankPorwal - 答案已经被编辑,将值转换为数字。 - jezrael
1
@jezrael 这个非常好用。感谢您的所有帮助。 - Mayank Porwal
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接