如何用transform/map在Python中实现分组条件减法创建新列
Pandas 基于分组条件减法创建新列
需求:对Pandas DataFrame按a列分组,提取每组中b列等于2对应的c列值,再用该组所有c列值减去此值生成新列d,要求使用transform或map函数实现。
示例数据
import pandas as pd data = [ ["R", 1, 2], ["R", 2, 4], ["R", 3, 6], ["R", 4, 8], ["S", 0, 5], ["S", 1, 4], ["S", 2, 1], ["S", 3, 3]] df = pd.DataFrame(data=data, columns=["a", "b", "c"])
原始输出:
a b c 0 R 1 2 1 R 2 4 2 R 3 6 3 R 4 8 4 S 0 5 5 S 1 4 6 S 2 1 7 S 3 3
期望输出:
a b c d 0 R 1 2 -2 1 R 2 4 0 2 R 3 6 2 3 R 4 8 4 4 S 0 5 4 5 S 1 4 3 6 S 2 1 0 7 S 3 3 2
方法1:使用transform实现
transform可在分组后返回与原DataFrame同长度的结果,适配场景需求:
# 按a分组,提取每组b=2对应的c值,通过transform广播到组内所有行 df['d'] = df['c'] - df.groupby('a')['c'].transform(lambda x: x[df.loc[x.index, 'b'] == 2].iloc[0])
说明:
df.groupby('a')['c'].transform(...):对每个分组的c列执行自定义逻辑- 函数内通过
x.index获取当前分组的行索引,匹配b列等于2的行并取出对应c值(假设每组仅存在一个b=2的行),transform会自动将该值广播到组内所有行 - 用原
c列减去广播后的基准值,得到目标列d
方法2:使用map实现
先构建分组基准值字典,再通过map匹配计算差值:
# 构建a列与b=2对应c值的映射字典 ref_dict = df[df['b'] == 2].set_index('a')['c'].to_dict() # 用map匹配每行的a值,获取基准值后计算差值 df['d'] = df['c'] - df['a'].map(ref_dict)
说明:
- 先筛选出
b=2的行,将a设为索引并转为字典,键为a的取值,值为对应c值 df['a'].map(ref_dict)为每行匹配到对应的基准值- 原
c列减去基准值得到d列
两种方法均能得到期望结果:map方式代码更简洁、效率更高;transform更适合分组内需要复杂逻辑处理的场景。
内容的提问来源于stack exchange,提问作者Nazanin
相关产品推荐
相关产品推荐

