Pandas按月份分组聚合时新增最大收支列的报错问题
解决方法:正确使用pandas聚合生成自定义列
首先得指出你之前的问题所在:你在agg()里用了'total_in'、'largest in'这类新列名作为字典的键,但pandas会把这些键当成原DataFrame的列名来查找——而你的原DF里根本没有这些列,自然会触发Key Error。
正确的思路是:针对原DF中已有的in、out、balance列,分别指定要应用的聚合函数,同时给聚合后的结果命名成你想要的新列名。下面是两种高效的实现方式:
方式一:使用命名聚合(推荐,可读性更高)
这种方式是pandas 0.25+支持的语法,直接在agg()里通过新列名=(原列名, 聚合函数)的形式定义,非常直观:
# 第一步:先把date列转换成datetime类型(必须!否则分组会失效) df['date'] = pd.to_datetime(df['date'], format='%d/%m/%Y') # 第二步:按月份分组并聚合 df2 = df.groupby(pd.Grouper(key='date', freq='M')).agg( total_in=('in', 'sum'), # 对in列求和,命名为total_in total_out=('out', 'sum'), # 对out列求和,命名为total_out largest_in=('in', 'max'), # 对in列取最大值,命名为largest_in largest_out=('out', 'max'), # 对out列取最大值,命名为largest_out final_balance=('balance', 'last')# 取balance列的最后一个值,命名为final_balance )
注意:
pd.TimeGrouper在新版本pandas中已经被pd.Grouper替代,所以用pd.Grouper(key='date', freq='M')来指定按date列的月份分组更稳妥。
方式二:先聚合再重命名列
如果你使用的pandas版本较低,不支持命名聚合,可以先按原列聚合,再扁平化列名并重命名:
# 先转换date列类型 df['date'] = pd.to_datetime(df['date'], format='%d/%m/%Y') # 分组聚合,每个原列对应多个聚合函数 df2 = df.groupby(pd.Grouper(key='date', freq='M')).agg( {'in': ['sum', 'max'], 'out': ['sum', 'max'], 'balance': ['last']} ) # 扁平化多级列名,并重命名成你想要的名称 df2.columns = ['total_in', 'largest_in', 'total_out', 'largest_out', 'final_balance'] # 可选:如果需要把date从索引转回普通列 df2 = df2.reset_index()
这两种方法都不需要修改原DataFrame,直接在聚合过程中生成你需要的所有新列,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Jasper
相关产品推荐
相关产品推荐

