Python:按组添加相对值(C/组内B='one'的C值)问题求助
按分组计算指定基准比值的问题解决
原始数据
import pandas as pd df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], 'B' : ['one', 'one', 'two', 'two', 'three', 'three', 'four', 'five'], 'C' : [2,3,4,9,12,12,17,13]})
需求
新增一列New,值为按A分组后,每组内C的数值除以该组中B='one'对应的C值,期望输出如下:
A B C New 0 foo one 2 1.0 1 bar one 3 1.0 2 foo two 4 2.0 3 bar two 9 3.0 4 foo three 12 6.0 5 bar three 12 4.0 6 foo four 17 8.5 7 foo five 13 6.5
错误代码及输出
用户编写的代码:
grouped = df.groupby(['A']).head(7) grouped['new']= grouped['C']/df[grouped['B']=='one']['C']
输出结果出现大量NaN:
A B C new 0 foo one 2 1.0 1 bar one 3 1.0 2 foo two 4 NaN 3 bar two 9 NaN 4 foo three 12 NaN 5 bar three 12 NaN 6 foo four 17 NaN 7 foo five 13 NaN
错误原因
df[grouped['B']=='one']['C']仅能获取到两行数据(B='one'的行),而grouped['C']是8行数据,直接相除时因索引不匹配,仅索引对应的两行能计算出结果,其余行无法匹配导致生成NaN。groupby(['A']).head(7)未起到分组计算的作用,对结果无实际帮助。
正确解法
方法一:使用transform实现分组基准值提取
通过groupby结合transform,在每个分组内提取B='one'对应的C值,并保持与原DataFrame相同的长度,直接进行除法运算:
df['New'] = df['C'] / df.groupby('A')['C'].transform(lambda x: x[df.loc[x.index, 'B'] == 'one'].iloc[0])
方法二:先构建基准值字典再映射计算
先提取每个A分组对应的B='one'的C值存入字典,再通过映射匹配到每行数据后计算比值:
# 构建分组基准值字典 base_dict = df[df['B'] == 'one'].set_index('A')['C'].to_dict() # 计算比值 df['New'] = df['C'] / df['A'].map(base_dict)
最终输出
两种方法均可得到符合预期的结果:
A B C New 0 foo one 2 1.0 1 bar one 3 1.0 2 foo two 4 2.0 3 bar two 9 3.0 4 foo three 12 6.0 5 bar three 12 4.0 6 foo four 17 8.5 7 foo five 13 6.5
内容的提问来源于stack exchange,提问作者Lilly
相关产品推荐
相关产品推荐

