如何用Python Pandas按Key分组,基于DataFrame值±0.5范围求和
解决方案:Pandas实现分组内数值范围求和
实现代码
import pandas as pd df = pd.DataFrame({'key':[ 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C'], 'value':[.1, 0.244, 0.373, 0.514, 0.663, 0.786, 0.902, 1.01, 1.151, 1.295, 1.434, 1.541, 1.679, 1.793, 1.94, 2.049, 2.164, 2.284, 2.432, 2.533, 2.68, 2.786, 2.906, 3.008, 3.136], 'desired_ouput':[1.231, 1.894, 2.68, 3.582, 3.482, 3.238, 2.865, 4.89, 6.431, 9.903, 11.843, 10.833, 11.731, 11.731, 9.002, 7.461, 11.462, 12.093, 17.785, 20.793, 21.765, 21.765, 19.481, 17.049, 14.516]}) def calculate_range_sum(group): values = group['value'].values # 生成布尔矩阵:判断每个value是否在当前行value的±0.5范围内 mask = (values >= values[:, None] - 0.5) & (values <= values[:, None] + 0.5) # 矩阵乘法快速计算每行符合条件的value总和 sums = mask.dot(values) return pd.Series(sums, index=group.index) # 应用分组计算并对齐结果 df['calculated_output'] = df.groupby('key').apply(calculate_range_sum).reset_index(level=0, drop=True) # 验证结果(保留三位小数后与期望输出一致) print(df[['desired_ouput', 'calculated_output']].round(3))
思路说明
- 广播机制生成掩码:利用NumPy的广播特性,将一维的
value数组扩展为二维布尔矩阵,一次性完成所有行的范围判断,避免逐行循环。 - 矩阵乘法求和:通过
mask.dot(values)直接对每行的筛选结果求和,比循环调用sum()效率更高,尤其适合大规模数据集。 - 结果对齐:
groupby.apply结合reset_index确保计算结果与原DataFrame的行索引完全匹配,无需手动处理分组后的索引问题。
验证结果
运行代码后,calculated_output列保留三位小数后与desired_ouput完全一致,符合需求。
内容的提问来源于stack exchange,提问作者wolfy
相关产品推荐
相关产品推荐

