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

如何在Pandas DataFrame中按质量条件设置分组极值?

解决方案:带质量条件的DataFrame分组值替换

问题背景

给定如下示例DataFrame:

import pandas as pd

lst = [['PF2', 'E1', -500, -127, 199971, 200164, True, True], 
       ['PR2', 'E1', -500, -167, 199655, 200124, True, True],
       ['PF2', 'E1', -500, -167, 199645, 200124, False, True],
       ['PF2', 'E1', -400, -127, 199971, 200564, True, True], 
       ['PR2', 'E1', -400, -167, 199155, 200324, True, True]]

df = pd.DataFrame(lst, columns=["Name", "Part", "Rel_s", 
                                "Rel_e", "Abs_s", "Abs_e",
                                "Quality_Start", "Quality_End"])

需求是:

  1. 将Abs_s替换为Part+Rel_s分组中仅Quality_Start=True的数据的最小值;若分组内无符合条件的数据,保留原数值。
  2. 将Abs_e替换为Part+Rel_e分组中仅Quality_End=True的数据的最大值;若分组内无符合条件的数据,保留原数值。

原代码未考虑质量条件,需要优化。


解决方案

方法1:分组映射法(简洁高效)

先筛选符合质量条件的数据计算分组统计值,再通过映射回填到原DataFrame,无匹配时保留原值:

# 计算符合Quality_Start=True的Part+Rel_s分组最小Abs_s
abs_s_min = df[df['Quality_Start']].groupby(["Part", "Rel_s"])['Abs_s'].min()
# 映射回原DataFrame,无对应分组则保留原Abs_s
df['Abs_s'] = df.apply(
    lambda row: abs_s_min.get((row['Part'], row['Rel_s']), row['Abs_s']),
    axis=1
)

# 计算符合Quality_End=True的Part+Rel_e分组最大Abs_e
abs_e_max = df[df['Quality_End']].groupby(["Part", "Rel_e"])['Abs_e'].max()
# 映射回原DataFrame,无对应分组则保留原Abs_e
df['Abs_e'] = df.apply(
    lambda row: abs_e_max.get((row['Part'], row['Rel_e']), row['Abs_e']),
    axis=1
)

验证结果:
对于Part=E1, Rel_s=-500的分组,符合Quality_Start=True的行是第0、1行,Abs_s最小值为199655,会替换该分组所有行的Abs_s(包括第2行原199645),完全符合需求。

方法2:transform结合条件筛选

直接在分组transform中加入质量判断,过滤不符合条件的数据后计算统计值,无有效数据时保留原值:

# 处理Abs_s:仅用Quality_Start=True的数据计算分组最小值
df['Abs_s'] = df.groupby(["Part", "Rel_s"])['Abs_s'].transform(
    lambda x: x.where(df.loc[x.index, 'Quality_Start']).min()
).fillna(df['Abs_s'])

# 处理Abs_e:仅用Quality_End=True的数据计算分组最大值
df['Abs_e'] = df.groupby(["Part", "Rel_e"])['Abs_e'].transform(
    lambda x: x.where(df.loc[x.index, 'Quality_End']).max()
).fillna(df['Abs_e'])

逻辑说明:

  • x.where(df.loc[x.index, 'Quality_Start'])会将分组内Quality_Start=False的Abs_s设为NaN,分组计算min时自动忽略NaN;
  • 若分组内无符合条件的数据,transform返回NaN,此时用fillna(df['Abs_s'])保留原数值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 06:48:17