Python中按两列分组并基于条件减法生成新列的实现方法
解决方案
先定义示例DataFrame(假设你的数据结构如下):
import pandas as pd df = pd.DataFrame({ 'A': [1,1,1,2,2,2], 'B': [1,2,3,1,2,3], 'C': [10,20,30,5,15,25], 'D': ['X','X','X','Y','Y','Y'] })
期望输出的e列应为:[-10, 0, 10, -10, 0, 10]
方法1:使用transform实现
transform能在分组后返回与原DataFrame长度一致的结果,完美适配这个场景:
# 按A和D分组,提取每组中B=2对应的C值,用transform广播到整组 df['e'] = df['C'] - df.groupby(['A', 'D'])['C'].transform(lambda x: x[df.loc[x.index, 'B'] == 2].iloc[0])
代码说明:
groupby(['A', 'D'])['C']:按A、D列分组,聚焦C列数据transform(lambda x: x[df.loc[x.index, 'B'] == 2].iloc[0]):对每组执行lambda函数,通过索引匹配找到该组中B=2对应的C值,再用transform将这个值广播到组内所有行- 用原C列减去广播后的基准值,得到新列
e
方法2:使用map结合分组结果实现
先预先计算每组对应的基准值,再通过map匹配到原DataFrame:
# 先计算每组(A,D)对应的B=2的C值,生成字典映射 base_values = df[df['B'] == 2].set_index(['A', 'D'])['C'].to_dict() # 用map将每行的(A,D)对应到基准值,再做减法 df['e'] = df['C'] - df.set_index(['A', 'D']).index.map(base_values)
代码说明:
df[df['B'] == 2].set_index(['A', 'D'])['C'].to_dict():筛选出B=2的行,以(A,D)为索引转成字典,键为(A,D)元组,值为对应C值df.set_index(['A', 'D']).index.map(base_values):把原DataFrame索引换成(A,D),用map匹配字典中的基准值,得到每行对应的基准值序列- 原C列减去该序列,得到新列
e
注意事项
- 如果每组存在多个B=2的行,需调整逻辑:比如用
mean()取平均值,或明确指定取第一个/最后一个,避免iloc[0]报错 - 如果某组没有B=2的行,会返回NaN,可根据需求用
fillna()处理
内容的提问来源于stack exchange,提问作者Nazanin
相关产品推荐
相关产品推荐

