【问题标题】:How do you rename all columns in multi level group by in pandas 0.20.1+如何在 pandas 0.20.1+ 中重命名多级分组中的所有列
【发布时间】:2017-05-10 14:23:51
【问题描述】:

随着 Pandas 0.20.1 的发布,groupby.agg() 的功能有了新的弃用,其中包含用于重命名的字典。

Deprecation documentation

我正在尝试找到更新代码以解决此问题的最佳方法,但是我正在努力解决我目前如何使用此重命名功能。

当我进行聚合时,我经常为每个源列设置多个函数,并且我一直在使用此重命名功能来获取具有这些新列名称的单级索引。

例子:

df = pd.DataFrame({'A': [1, 1, 1, 2, 2],'B': range(5),'C': range(5)})

In [30]: df
Out[30]: 
   A  B  C
0  1  0  0
1  1  1  1
2  1  2  2
3  2  3  3
4  2  4  4

frame = df.groupby('A').agg({'B' : {'foo':'sum'}, 'C': {'bar' : 'min', 'bar2': 'max'}})

结果:

Out[33]: 
    B   C     
  foo bar bar2
A             
1   3   0    2
2   7   3    4

我通常会这样做:

frame = pd.DataFrame(frame).reset_index(col_level=1)

frame.columns = frame.columns.get_level_values(1)

frame
Out[42]: 
   A  foo  bar  bar2
0  1    3    0     2
1  2    7    3     4

所以我正在寻找获得作为单级索引但具有新的唯一列名的结果数据框的好方法。其中多个列源自单个源列的聚合。非常感谢任何最佳方法的建议。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    这在0.20.1 版本中完美运行:

    d = {'sum':'foo','min':'bar','max':'bar2'}
    frame = df.groupby('A').agg({'B' : ['sum'], 'C': ['min', 'max']}).rename(columns=d)
    frame.columns = frame.columns.droplevel(0)
    frame = frame.reset_index()
    print (frame)
       A  foo  bar  bar2
    0  1    3    0     2
    1  2    7    3     4
    

    如果有多个mins:

    d = {'B_sum':'foo','C_min':'bar','C_max':'bar2'}
    frame = df.groupby('A').agg({'B' : ['sum'], 'C': ['min', 'max']})
    frame.columns = frame.columns.map('_'.join)
    frame = frame.reset_index().rename(columns=d)
    print (frame)
       A  foo  bar  bar2
    0  1    3    0     2
    1  2    7    3     4
    

    【讨论】:

    • 谢谢,总的来说,我认为我可以使用它。我面临的唯一挑战是是否多次使用相似或相同的 agg 函数。我经常在我的列中使用 lambda 函数。简单的例子是如果我添加:'B' : ['sum','min'] 然后有两列作为 'min'。
    • 是的,那么需要先用Multiindex创建Index,更简单的解决方案是用map。检查编辑的答案。
    • 完美。有道理!
    • 感谢您对熊猫相关问题的一贯贡献。它向我介绍了一个新功能droplevel
    【解决方案2】:

    这里有一个更短的替代方案:

    In [78]: d={'C_min':'min_C', 'C_sum':'sum_C','B_min':'min_B','B_sum':'sum_B'}
    
    In [79]: frame
    Out[79]:
        C       B
      min sum min sum
    A
    1   0   3   0   3
    2   3   7   3   7
    
    In [80]: frame.columns = frame.columns.map('_'.join).to_series().map(d)
    
    In [81]: frame
    Out[81]:
       min_C  sum_C  min_B  sum_B
    A
    1      0      3      0      3
    2      3      7      3      7
    

    【讨论】:

    • 不必手动输入映射d,而是使用.swaplevel()。因此,整个事情看起来frame.columns.swaplevel().map('_'.join)
    【解决方案3】:

    您可以在列上调用droplevel,然后调用reset_index

    In [46]:
    frame.columns = frame.columns.droplevel(0)
    frame = frame.reset_index()
    frame
    
    Out[46]:
       A  bar  bar2  foo
    0  1    0     2    3
    1  2    3     4    7
    

    【讨论】:

    • 在 Pandas 0.23.4 中,np.columns.droplevel() 不再可用。
    猜你喜欢
    • 2018-10-27
    • 2018-01-14
    • 1970-01-01
    • 2020-07-18
    • 2017-03-05
    • 1970-01-01
    • 1970-01-01
    • 2019-09-17
    • 2018-08-23
    相关资源
    最近更新 更多