DataFrame分组平均计算问题:最后一行数据未被纳入计算
解决方案:计算column_a为0的分组的value_b平均值
原代码问题分析
- 使用
df.iloc[0:-1].iterrows()遍历会直接遗漏最后一行,导致最后一组column_a为0的行无法处理; - 直接用
df['sum_c'][i]这种链式索引赋值,容易触发SettingWithCopyWarning,还可能导致数据赋值失败; - 第二个循环中判断
df.loc[m+1, 'sum_c']时,若m为最后一行索引会出现越界报错,这也是你用iloc[0:-1]的原因,但同时带来了遗漏问题。
改进方案1:优化循环逻辑
先完整计算所有行的sum_c和count_d,再处理avg_e的计算:
import pandas as pd # 初始化列,避免链式索引问题 df['sum_c'] = 0 df['count_d'] = 0 current_sum = 0 current_count = 0 # 遍历所有行计算sum_c和count_d for idx, row in df.iterrows(): if row['column_a'] == 0: current_sum += row['value_b'] current_count += 1 df.loc[idx, 'sum_c'] = current_sum df.loc[idx, 'count_d'] = current_count else: current_sum = 0 current_count = 0 df.loc[idx, 'sum_c'] = current_sum df.loc[idx, 'count_d'] = current_count # 初始化avg_e列 df['avg_e'] = None # 标记连续分组:当column_a与上一行不同时,分组ID+1 df['group_id'] = (df['column_a'] != df['column_a'].shift()).cumsum() # 遍历每个分组,计算0分组的平均值 for _, group_df in df.groupby('group_id'): # 判断当前分组是否全为0 if (group_df['column_a'] == 0).all(): # 取分组最后一行的sum_c和count_d计算平均值 avg = group_df['sum_c'].iloc[-1] / group_df['count_d'].iloc[-1] # 将平均值赋值给该分组的所有行(若只需最后一行,改为df.loc[group_df.index[-1], 'avg_e'] = avg) df.loc[group_df.index, 'avg_e'] = avg # 可选:删除临时的group_id列 df.drop('group_id', axis=1, inplace=True)
改进方案2:纯Pandas分组实现(更高效)
利用Pandas分组功能直接完成,避免循环,适合大数据量场景:
import pandas as pd # 标记连续的0分组 df['group_id'] = (df['column_a'] != df['column_a'].shift()).cumsum() # 计算每个分组的累计sum和count df['sum_c'] = df.groupby('group_id')['value_b'].cumsum().where(df['column_a'] == 0, 0) df['count_d'] = df.groupby('group_id').cumcount().where(df['column_a'] == 0, 0) + 1 df['count_d'] = df['count_d'].where(df['column_a'] == 0, 0) # 计算每个0分组的平均值,并填充到组内所有行 group_avg = df[df['column_a'] == 0].groupby('group_id')['sum_c'].last() / df[df['column_a'] == 0].groupby('group_id')['count_d'].last() df['avg_e'] = df['group_id'].map(group_avg) # 可选:删除临时的group_id列 df.drop('group_id', axis=1, inplace=True)
关键说明
- 两种方案都能处理最后一组column_a为0的情况,不会遗漏;
- 方案1保留了循环逻辑,更贴近原代码思路;方案2用Pandas内置方法实现,效率更高;
- 若只需要在分组切换前的最后一行设置
avg_e,修改赋值逻辑为仅针对分组最后一行索引即可。
内容的提问来源于stack exchange,提问作者Nazmi Husaini
相关产品推荐
相关产品推荐

