如何用Pandas的iterrows()比较多行值并计算分组均值?
修正Pandas iterrows()分组计算平均值并填充最后一行的代码
需求说明
使用Pandas的iterrows()方法比较DataFrame中当前行与下一行的数值,按Month和Year分组计算3_Mo列的平均值,仅将平均值填入每组最后一行的Avg_3_Mo列,其余行保持0。
初始代码及问题
用户提供的初始代码如下,其中比较当前行与下一行Month值的逻辑无法正常运行:
yc_df = pd.DataFrame([[7,1,1990,0], [7.5,1,1990,0], [8,2,1990,0],[8.5,2,1990,0]], columns=['3_Mo', 'Month','Year', 'Avg_3_Mo']) #initially, yc_df['Avg_3_Mo'] has been initialised to all 0s. for index, row in yc_df.iterrows(): if math.isnan(row['3_Mo']) == False: count += 1 sum_3mo += row['3_Mo'] avg_3mo = sum_3mo/count if row['Month']!= (row+1)['Month']: **#Here I want to compare the current row value with the next row** row['Avg_3_Mo'] = avg_3mo sum_3mo = 0 avg_3mo = 0
预期输出
3_Mo Month Year Avg_3_Mo 0 7 1 1990 0 1 7.5 1 1990 7.25 2 8 2 1990 0 3 8.5 2 1990 8.25
问题分析
原代码存在几个核心问题:
- 错误使用
row+1获取下一行:row是Series对象,直接加法是对元素值做运算,而非获取下一行数据,需通过索引index+1访问原DataFrame的下一行 - 变量未初始化:
count、sum_3mo未提前赋值,运行会抛出NameError - 修改行数据无效:
iterrows()返回的是行的副本,直接修改row不会同步到原DataFrame,需通过索引定位修改 - 未处理最后一行:最后一行没有下一行,需要直接作为组的末尾填充平均值
- 分组逻辑不完整:仅对比
Month,未考虑Year,不符合需求中的分组规则
修正后的代码
import pandas as pd import math yc_df = pd.DataFrame([[7,1,1990,0], [7.5,1,1990,0], [8,2,1990,0],[8.5,2,1990,0]], columns=['3_Mo', 'Month','Year', 'Avg_3_Mo']) # 初始化累计计算的变量 count = 0 sum_3mo = 0 avg_3mo = 0 for index, row in yc_df.iterrows(): # 跳过空值(若存在),累计当前行的3_Mo值 if not math.isnan(row['3_Mo']): count += 1 sum_3mo += row['3_Mo'] avg_3mo = sum_3mo / count # 判断当前行是否为所在分组的最后一行 is_last_in_group = False # 非最后一行时,对比下一行的Month和Year if index < len(yc_df) - 1: next_row = yc_df.iloc[index + 1] if row['Month'] != next_row['Month'] or row['Year'] != next_row['Year']: is_last_in_group = True else: # 最后一行直接判定为分组末尾 is_last_in_group = True if is_last_in_group: # 通过索引修改原DataFrame的Avg_3_Mo列 yc_df.loc[index, 'Avg_3_Mo'] = avg_3mo # 重置累计变量,准备下一组计算 count = 0 sum_3mo = 0 avg_3mo = 0 # 打印结果 print(yc_df)
运行结果
3_Mo Month Year Avg_3_Mo 0 7.0 1 1990 0.00 1 7.5 1 1990 7.25 2 8.0 2 1990 0.00 3 8.5 2 1990 8.25
关键修改说明
- 提前初始化
count、sum_3mo、avg_3mo,避免未定义错误 - 使用
yc_df.iloc[index+1]正确获取下一行数据,同时对比Month和Year两个分组键 - 处理最后一行的边界情况,确保分组末尾都能填充平均值
- 通过
yc_df.loc[index, 'Avg_3_Mo']修改原DataFrame,保证修改生效 - 保留空值判断逻辑,增强代码鲁棒性
内容的提问来源于stack exchange,提问作者Ansh Gupta
相关产品推荐
相关产品推荐

