如何用更简洁方式(如lambda函数)聚合生成带计算列的新DataFrame
Pandas分组计算加权平均的简洁实现方案
需求说明
从原DataFrame生成新DataFrame,要求:
- 移除
ctry列 - 按
rgn和year字段分组 - 计算
value列,公式为:每组内∑(val1×val2) ÷ ∑val2
已通过分步代码实现,现寻求更简洁的写法(比如结合lambda函数)。
示例数据
import pandas as pd df = pd.DataFrame( [ ['A','X',2000,5,3],['A','X',2001,6,2], ['B','X',2000,6,3],['B','X',2001,7,2], ['C','Y',2000,10,4],['C','Y',2001,12,4], ['D','Y',2000,11,2],['D','Y',2001,15,1] ], columns=['ctry','rgn','year','val1','val2'] )
期望结果
rgn year value 0 X 2000 5.500000 1 X 2001 6.500000 2 Y 2000 10.333333 3 Y 2001 12.600000
现有分步实现代码
df['calc'] = df['val1'] * df['val2'] new_df = df.groupby(['rgn', 'year']).sum() new_df['value'] = new_df['calc']/new_df['val2'] new_df = new_df.reset_index().rename_axis(None, axis=1) new_df = new_df.drop(columns=['ctry', 'val1', 'val2', 'calc'])
简洁实现方式
以下几种写法无需创建中间列,直接完成计算:
方法1:groupby.apply结合lambda
new_df = df.groupby(['rgn', 'year'], as_index=False).apply( lambda g: pd.Series({'value': (g['val1'] * g['val2']).sum() / g['val2'].sum()}) )
方法2:agg计算分子分母后合并
new_df = df.groupby(['rgn', 'year'], as_index=False).agg( numerator=('val1', lambda x: (x * df.loc[x.index, 'val2']).sum()), denominator=('val2', 'sum') ).assign(value=lambda x: x['numerator'] / x['denominator']).drop(columns=['numerator', 'denominator'])
方法3:利用numpy.average直接计算加权平均
import numpy as np new_df = df.groupby(['rgn', 'year'], as_index=False).agg( value=('val1', lambda x: np.average(x, weights=df.loc[x.index, 'val2'])) )
内容的提问来源于stack exchange,提问作者M S
相关产品推荐
相关产品推荐

