如何在Python DataFrame中按分组计算阈值以上均值并生成新列
解决步骤及代码实现
直接给你一套可落地的代码,搭配模拟数据,你可以替换成自己的真实数据使用:
1. 模拟示例数据(替换为你的真实DataFrame即可)
import pandas as pd import numpy as np # 分数表:日期+各人员分数(含NaN值) score_df = pd.DataFrame({ '日期': ['2024-01-01', '2024-01-02', '2024-01-03'], 'James': [4, 2, np.nan], 'Jamie': [5, 3, 1], 'Alice': [2, 4, 5], 'Bob': [np.nan, 3, 6] }) # 人员分组表:姓名+分组(guy/girl) group_df = pd.DataFrame({ '姓名': ['James', 'Jamie', 'Alice', 'Bob'], '分组': ['guy', 'girl', 'girl', 'guy'] })
2. 替换低于阈值的分数为NaN
先筛选出分数列(排除日期列),用where方法把≤3的数值替换成NaN:
# 提取所有分数列(去掉日期列) score_cols = score_df.columns.drop('日期') # 替换逻辑:分数>3则保留原值,否则设为NaN score_df[score_cols] = score_df[score_cols].where(score_df[score_cols] > 3, np.nan)
3. 按分组计算每行的组内均值
先把分组表转成「姓名-分组」的字典,拆分出两组对应的列名,最后按行计算均值(自动忽略NaN):
# 把分组表转成字典,方便匹配分数表的列名 group_map = group_df.set_index('姓名')['分组'].to_dict() # 拆分出guy和girl对应的分数列名 guy_cols = [name for name, group in group_map.items() if group == 'guy'] girl_cols = [name for name, group in group_map.items() if group == 'girl'] # 计算每行的组内均值,skipna=True自动忽略NaN值 score_df['guy_mean'] = score_df[guy_cols].mean(axis=1, skipna=True) score_df['girl_mean'] = score_df[girl_cols].mean(axis=1, skipna=True)
你之前得到全NaN的常见原因
- 分组表的姓名和分数表的列名不匹配(比如大小写、空格差异),导致筛选出的
guy_cols/girl_cols是空列表,计算均值自然返回NaN - 计算均值时没加
axis=1,默认按列计算全局均值,而非每行的组内均值 - 替换阈值时逻辑搞反(比如用了
mask而非where),或者误修改了日期列导致计算出错
内容的提问来源于stack exchange,提问作者Hal
相关产品推荐
相关产品推荐

