You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas中分组并在组内过滤后添加聚合列

需求:为DataFrame添加分组条件聚合列

给定如下DataFrame:

import pandas as pd

df = pd.DataFrame({
    "col1": [1, 2, 3, 4, 5],
    "col2": ["b", "b", "b", "a", "b"],
    "col3": [6, 2, 11, 1, 3]
})

需要新增一列mean_col,规则为:对每一行,计算同col2分组下、col3值小于当前行col3值的col1的均值。预期结果如下:

pd.DataFrame({
    "col1": [1, 2, 3, 4, 5],
    "col2": ["b", "b", "b", "a", "b"],
    "col3": [6, 2, 11, 1, 3],
    "mean_col": [3.5, None, 2.666, None, 2.0]
})

已通过iterrows循环实现,但希望使用更高效的向量化/分组操作替代遍历。


解决方案1:分组后结合apply处理单组逻辑

利用groupby('col2')分组后,对每组内的行单独筛选符合条件的记录并计算均值:

def get_group_mean(row, group_data):
    # 筛选组内col3小于当前行col3的col1值
    valid_col1 = group_data.loc[group_data['col3'] < row['col3'], 'col1']
    return valid_col1.mean() if not valid_col1.empty else None

# 分组后逐行应用计算逻辑
df['mean_col'] = df.groupby('col2').apply(
    lambda g: g.apply(lambda row: get_group_mean(row, g), axis=1)
).reset_index(level=0, drop=True)

# 保留三位小数对齐预期结果
df['mean_col'] = df['mean_col'].round(3)
print(df)

输出结果:

col1 col2  col3  mean_col
0     1    b     6      3.500
1     2    b     2        NaN
2     3    b    11      2.667
3     4    a     1        NaN
4     5    b     3      2.000

解决方案2:自连接+分组聚合(高性能向量化方案)

通过自连接生成同组内的所有行对,筛选符合条件的记录后批量计算均值,完全避免行级遍历:

# 自连接,保留同col2的所有行组合
merged_df = df.merge(df, on='col2', suffixes=('', '_other'))
# 筛选出另一行col3小于当前行的记录
filtered = merged_df[merged_df['col3_other'] < merged_df['col3']]
# 按原行索引分组,计算符合条件的col1均值
mean_result = filtered.groupby(filtered.index)['col1_other'].mean().round(3)
# 将结果合并回原DataFrame,无匹配项填充NaN
df['mean_col'] = mean_result
print(df)

该方法依赖pandas的向量化操作,在数据量较大时性能远优于行遍历。


内容的提问来源于stack exchange,提问作者Dom McEwen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 19:47:05