如何基于Date和Location分组高效生成DataFrame的Relative_Value列?
高效计算分组相对值的Pandas实现方案
需求是给包含Date、Location、Value列的时间序列DataFrame新增Relative_Value列,该列值为每行Value除以其对应Date+Location分组的Value总和。比如Date=20220101、Location=FE时,Value=4的行计算为4/(4+2+6+4+1)=0.235。
原实现用了groupby.apply,但这种方法效率偏低,以下是更高效的实现方式:
可复现代码
import pandas as pd df1 = pd.DataFrame({ 'Date':[20220101, 20220101, 20220101, 20220101, 20220101, 20220101, 20220101, 20220101, 20220102, 20220102, 20220102, 20220102, 20220102, 20220102, 20220102, 20220102], 'Location':['FE', 'FE', 'FE', 'FE', 'FE', 'RP', 'RP', 'RP', 'FE', 'FE', 'FE', 'FE', 'RP', 'RP', 'RP', 'RP'], 'Value':[4, 2, 6, 4, 1, 4, 6, 4, 1, 3, 4, 1, 8, 4, 5, 9]})
高效实现代码
# 复制原DataFrame避免修改原数据 df2 = df1.copy() # 用transform获取分组总和,直接做向量化除法 df2['Relative_Value'] = df2['Value'] / df2.groupby(['Date', 'Location'])['Value'].transform('sum') # 验证结果(以Date=20220101、Location=FE组为例) print(df2[(df2['Date'] == 20220101) & (df2['Location'] == 'FE')])
为什么这个方法更高效
- 向量化运算:
transform('sum')会返回与原DataFrame长度一致的Series,每个元素对应所在分组的Value总和,直接做除法是Pandas原生的向量化操作,避免了apply逐组执行函数的额外开销。 - 精准处理目标列:原方法的
apply(lambda x: x/sum(x))会对分组内的所有列(包括Date、Location)执行除法,完全没必要,而我们只需要针对Value列计算,用transform可以精准定位目标列,减少不必要的计算。
当数据量较大时,这种方法的效率优势会非常明显。
内容的提问来源于stack exchange,提问作者fjurt
相关产品推荐
相关产品推荐

