【问题标题】:Pandas: Sort innermost column group-wise based on other multilevel columnPandas:根据其他多级列按组对最内列进行排序
【发布时间】:2021-03-09 06:49:59
【问题描述】:

考虑下面的df:

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}

pivot以上df:

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}

我想根据索引为(E, a) 的多级列对每组外列D 的最内列进行排序,该列是value 的降序。字典。

编辑:

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}
 


 

【问题讨论】:

    标签: python python-3.x pandas dataframe sorting


    【解决方案1】:

    使用Series.str.get 创建的助手MultiIndex column 的解决方案,然后按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}  
    

    【讨论】:

    • 你知道为什么这个灵魂会产生错误吗? x.sort_values(by=('E', 'a'), key=lambda x: x.get('value')) 或等效的 x.sort_values(by=('E', 'a'), key=lambda x: x['value'])
    • @IoaTzimas - 也许是新功能,所以有一些错误。
    • @jezrael 在我不必硬编码列 BCD 的情况下,您能否让这个解决方案有点笼统?我总是需要对最里面的列D进行排序,其余列(BC)可以相同。
    • @jezrael 感谢您的帮助。还有一种情况,要不要加样例数据?
    • @jezrael 这非常有效。谢谢大家的帮助。
    猜你喜欢
    • 2021-03-19
    • 1970-01-01
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    • 2021-10-09
    • 2020-02-29
    • 2023-03-28
    • 2019-11-28
    相关资源
    最近更新 更多