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

时间:2017-06-19 16:28:35

标签: python pandas 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

会产生以下警告:

  

FutureWarning:不推荐使用带重命名的dict   在将来的版本中删除返回super(DataFrameGroupBy,   self).aggregate(arg,* args,** kwargs)

我该如何避免这种情况?

6 个答案:

答案 0 :(得分:66)

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

使用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]})

enter image description here

创建返回系列的自定义函数
x内的变量my_agg是一个DataFrame

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'])

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

df.groupby('User').apply(my_agg)

enter image description here

最大的缺点是这个函数比cythonized aggregations

agg慢得多

使用groupby agg方法

的字典

由于其复杂性和某种模糊性,删除了使用字典字典。关于如何在github上改进此功能有一个ongoing discussion在这里,您可以在groupby调用后直接访问聚合列。只需传递您希望应用的所有聚合函数的列表。

df.groupby('User')['Amount'].agg(['sum', 'count'])

输出

       sum  count
User              
user1  18.0      2
user2  20.5      3
user3  10.5      1

仍然可以使用字典明确表示不同列的不同聚合,例如,如果有另一个名为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']})

输出

      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

答案 1 :(得分:10)

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

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")]})

答案 2 :(得分:6)

Pandas 0.25+ Aggregation relabeling的更新

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')

输出:

        Sum  Count
User              
user1  18.0      2
user2  20.5      3
user3  10.5      1

答案 3 :(得分:1)

这就是我所做的:

创建假数据集:

import pandas as pd
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]})
df

O / P:

    Amount  Score   User
0   10.0    9   user1
1   5.0 1   user2
2   8.0 8   user2
3   10.5    7   user3
4   7.5 7   user2
5   8.0 6   user1
6   9.0 9   user3

我首先使用户成为索引,然后使之成为groupby:

ans = df.set_index('User').groupby(level=0)['Amount'].agg([('Sum','sum'),('Count','count')])
ans

解决方案:

    Sum Count
User        
user1   18.0    2
user2   20.5    3
user3   19.5    2

答案 4 :(得分:1)

这对我有用,Pandas 版本 1.2.4

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

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

示例

# 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)

结果:

<头>
id 姓名1 name2_mean name2_custom_std
0 1 3 13 1.5
1 2 1 6 0.0
2 3 5 4 0.0

答案 5 :(得分:0)

将内部词典替换为正确命名的函数列表。

要重命名该函数,请使用以下实用程序函数:


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

分组依据语句变为:

def convert_aggr_spec(aggr_spec):
    return {
        col : [ 
            aliased_aggr(aggr,alias) for alias, aggr in aggr_map.items() 
        ]  
        for col, aggr_map in aggr_spec.items() 
    }

如果您有更大,可重用的聚合规范,则可以使用

进行转换
df.groupby(["User"]).agg(convert_aggr_spec({"Amount": {"Sum": "sum", "Count": "count"}}))

所以你可以说

public class Exercise  {
    public static void main(String[] r)
       {
        try{
        long a = 600851475143L; 
        System.out.println("the largest prime factor of " + a+ " is " +largestPrimeFactor(a) );
        }catch(Exception e)
        {
            e.printStackTrace();
        }
        }

    public static int largestPrimeFactor(long number) {
        int i;
        long copyOfInput = number;

        for (i = 2; i <= copyOfInput; i++) {
            if (copyOfInput % i == 0) {
                copyOfInput /= i;
                i--;
            }
        }
        return i;
    }
}

另请参阅https://github.com/pandas-dev/pandas/issues/18366#issuecomment-476597674