从Pandas聚合重命名结果列("FutureWarning:使用带重命名的dict已弃用")

Vic*_*ink 44 python aggregate rename pandas

我正在尝试对熊猫数据框进行一些聚合.这是一个示例代码:

import pandas as pd

df = pd.DataFrame({"User": ["user1", "user2", "user2", "user3", "user2", "user1"],
                  "Amount": [10.0, 5.0, 8.0, 10.5, 7.5, 8.0]})

df.groupby(["User"]).agg({"Amount": {"Sum": "sum", "Count": "count"}})

Out[1]: 
      Amount      
         Sum Count
User              
user1   18.0     2
user2   20.5     3
user3   10.5     1
Run Code Online (Sandbox Code Playgroud)

这会产生以下警告:

FutureWarning:使用带重命名的dict已弃用,将在以后的版本中返回super(DataFrameGroupBy,self).aggregate(arg,*args,**kwargs)

我怎么能避免这个?

Ted*_*rou 74

使用groupby apply并返回一个Series来重命名列

使用groupby apply方法执行聚合

  • 重命名列
  • 允许名称中的空格
  • 允许您以您选择的任何方式订购返回的列
  • 允许列之间的交互
  • 返回单级索引而不是MultiIndex

去做这个:

  • 创建传递给的自定义函数 apply
  • 此自定义函数作为DataFrame传递给每个组
  • 返回系列
  • 系列的索引将是新列

创建虚假数据

df = pd.DataFrame({"User": ["user1", "user2", "user2", "user3", "user2", "user1", "user3"],
                  "Amount": [10.0, 5.0, 8.0, 10.5, 7.5, 8.0, 9],
                  'Score': [9, 1, 8, 7, 7, 6, 9]})
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

创建一个返回系列自定义函数
的变量x里面的my_agg是一个数据帧

def my_agg(x):
    names = {
        'Amount mean': x['Amount'].mean(),
        'Amount std':  x['Amount'].std(),
        'Amount range': x['Amount'].max() - x['Amount'].min(),
        'Score Max':  x['Score'].max(),
        'Score Sum': x['Score'].sum(),
        'Amount Score Sum': (x['Amount'] * x['Score']).sum()}

    return pd.Series(names, index=['Amount range', 'Amount std', 'Amount mean',
                                   'Score Sum', 'Score Max', 'Amount Score Sum'])
Run Code Online (Sandbox Code Playgroud)

将此自定义函数传递给groupby apply方法

df.groupby('User').apply(my_agg)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

最大的缺点是,这个功能会比慢得多aggcythonized聚合

使用groupby agg方法的字典

使用词典字典被删除了,因为它的复杂性和模糊性.有一个正在进行的讨论,关于如何提高在GitHub上,今后这个功能在这里,你可以直接在GROUPBY调用后访问聚集列.只需传递您希望应用的所有聚合函数的列表.

df.groupby('User')['Amount'].agg(['sum', 'count'])
Run Code Online (Sandbox Code Playgroud)

产量

       sum  count
User              
user1  18.0      2
user2  20.5      3
user3  10.5      1
Run Code Online (Sandbox Code Playgroud)

仍然可以使用字典来明确表示不同列的不同聚合,例如,如果有另一个名为的数字列,则为此Other.

df = pd.DataFrame({"User": ["user1", "user2", "user2", "user3", "user2", "user1"],
              "Amount": [10.0, 5.0, 8.0, 10.5, 7.5, 8.0],
              'Other': [1,2,3,4,5,6]})

df.groupby('User').agg({'Amount' : ['sum', 'count'], 'Other':['max', 'std']})
Run Code Online (Sandbox Code Playgroud)

产量

      Amount       Other          
         sum count   max       std
User                              
user1   18.0     2     6  3.535534
user2   20.5     3     5  1.527525
user3   10.5     1     4       NaN
Run Code Online (Sandbox Code Playgroud)

  • 但是假设您确实也想要重命名方面,在聚合之后具有与默认值不同的列名.是否有一些语法仍然可以获得此功能? (15认同)
  • 有关于命名的相同问题,因为我使用相同的col两次(一分钟和一个max)并且当我将结果放回对象时需要一种方法来唯一地引用它们. (2认同)
  • apply方法如何与'first'和'last'一起使用? (2认同)

小智 13

如果用一个元组列表替换内部字典,它就会删除警告消息

import pandas as pd

df = pd.DataFrame({"User": ["user1", "user2", "user2", "user3", "user2", "user1"],
                  "Amount": [10.0, 5.0, 8.0, 10.5, 7.5, 8.0]})

df.groupby(["User"]).agg({"Amount": [("Sum", "sum"), ("Count", "count")]})
Run Code Online (Sandbox Code Playgroud)

  • 这是一个没有记录和意外的功能,我强烈建议没有人使用这种语法,因为它可能在将来不起作用. (7认同)

Ann*_*nna 12

这对我有用,Pandas 版本1.2.4

对于每一列,我们添加一个由元组组成的列表:

df.groupby('column to group by').agg(
{'column name': [('new column name', 'function to apply')]})
Run Code Online (Sandbox Code Playgroud)

例子

# Create DataFrame
df=pd.DataFrame(data={'id':[1,1,2,3],'col1': [1,2,1,5], 'col2':[5,8,6,4]})

# Apply grouping 
grouped = df.groupby('id').agg({
                             'col1': [('name1', 'sum')], 
                             'col2': [('name2_mean', 'sum'), ('name2_custom_std', lambda x: np.std(x))]})

# Drop multi-index for columns and reset index
grouped.columns = grouped.columns.droplevel()
grouped.reset_index(inplace=True)
Run Code Online (Sandbox Code Playgroud)

结果:

ID 姓名1 名称2_平均值 name2_自定义_std
0 1 3 13 1.5
1 2 1 6 0.0
2 3 5 4 0.0


Sco*_*ton 6

熊猫0.25+ 聚合重新标记的更新

import pandas as pd

print(pd.__version__)
#0.25.0

df = pd.DataFrame({"User": ["user1", "user2", "user2", "user3", "user2", "user1"],
                  "Amount": [10.0, 5.0, 8.0, 10.5, 7.5, 8.0]})

df.groupby("User")['Amount'].agg(Sum='sum', Count='count')
Run Code Online (Sandbox Code Playgroud)

输出:

        Sum  Count
User              
user1  18.0      2
user2  20.5      3
user3  10.5      1
Run Code Online (Sandbox Code Playgroud)

  • 但在本例中,名称“Sum”和“Count”必须是有效的 Python 名称。您无法将“Sum”替换为“Sum of foos”。:( (2认同)
  • @Dror你可以使用这种格式 `df.groupby('User').agg(**{'sum of foos':pd.NamedAgg('Amount','sum'), 'count of foos':pd.NamedAgg ('金额','计数')})` (2认同)
  • @Dror您不需要包含`pd.NamedAgg`部分,这会缩短代码量。现在这是我的首选方式。传入一个前面带有“**”的字典。 (2认同)