Pandas按Name分组匹配Price1与Price2,将对应answer填充至新列
按分组填充匹配行的answer值到整组
问题场景
给定如下DataFrame,需要按Name列分组,找到每组中Price1与Price2相等的行,将该行的answer值填充到同组所有行的新列result中。
原始数据代码:
import pandas as pd d = { 'Name': ['Cat', 'Cat', 'Dog', 'Dog'], 'Price1': [2, 1, 10, 3], 'Price2': [5, 1, 7, 3], 'answer': ['A', 'B', 'C', 'D'] } data = pd.DataFrame(data=d)
原始数据结构:
| Name | Price1 | Price2 | answer | |
|---|---|---|---|---|
| 0 | Cat | 2 | 5 | A |
| 1 | Cat | 1 | 1 | B |
| 2 | Dog | 10 | 7 | C |
| 3 | Dog | 3 | 3 | D |
期望结果:
0 B 1 B 2 D 3 D Name: result, dtype: object
错误原因分析
第一种写法报错
ValueError: Can only compare identically-labeled Series objects:data.groupby('itemName')['Price1'].transform(lambda x: data['answer'][x==data['Price2']])问题出在
x==data['Price2']:x是分组后的Price1子Series,和全局的data['Price2']索引不匹配,无法直接比较。第二种写法仅匹配行有值,其余为NaN:
data.groupby('itemName')['Price1'].transform(lambda x: data['answer'][data['Price1']==data['Price2']])这里是全局判断
Price1==Price2,只给匹配行赋值,没有将值广播到同组的其他行。
正确解决方案
方法1:构建映射字典(高效简洁)
先筛选出所有Price1==Price2的行,构建Name到对应answer的映射字典,再通过map填充整列:
# 构建Name与匹配answer的映射 match_dict = data[data['Price1'] == data['Price2']].set_index('Name')['answer'].to_dict() # 填充result列 data['result'] = data['Name'].map(match_dict)
方法2:分组广播(适合复杂分组逻辑)
通过groupby.apply在每组内找到匹配的answer,并赋值给整组:
data['result'] = data.groupby('Name').apply( lambda group: group.assign(result=group[group['Price1'] == group['Price2']]['answer'].iloc[0]) )['result']
方法3:transform直接处理
利用transform传入组对象,提取匹配值并广播:
data['result'] = data.groupby('Name').transform( lambda g: g['answer'][g['Price1'] == g['Price2']].iloc[0] )['answer']
最终结果
执行任意一种方法后,data['result']都会得到期望的输出:
0 B 1 B 2 D 3 D Name: result, dtype: object
内容的提问来源于stack exchange,提问作者jojokids
相关产品推荐
相关产品推荐

