如何在Pandas中按ID分组将brick值与同组其他项值做除法?
Pandas分组计算:生成同组brick值与其他item值的比值列
现有如下Pandas DataFrame:
id item val 0 a tire 5 1 a brick 5 2 b wheel 9 3 b brick 6 4 c ice 6 5 c brick 3 6 d brick 3 7 d grass 6
需求说明
将每个同ID分组中brick的val值除以同组其他item的val值,生成新列per/brick,期望结果如下:
id item val per/brick 0 a tire 5 1 1 a brick 5 1 2 b wheel 9 0.7 3 b brick 6 1 4 c ice 6 .5 5 c brick 3 1 6 d brick 3 .5 7 d grass 6 2
错误尝试与问题分析
尝试通过for循环实现时出现错误:
perbrick=[] for x in df['id']: if df[df['id']==x & df['item']!='brick']: perbrick.append(df[(df['id']==x)&(df['item']=='brick')]['val']/df[df['id']==x]['val'] else: perbrick.append(1)
报错信息:TypeError: Cannot perform 'rand_' with a dtyped [object] array and scalar of type [bool]
错误原因
- 逻辑运算符优先级错误:
&的优先级高于==和!=,代码中df['id']==x & df['item']!='brick'会被错误解析为df['id'] == (x & df['item']!='brick'),导致布尔值与字符串类型的ID进行位运算,触发类型不匹配错误。 - 循环取值逻辑混乱:直接通过
df[df['id']==x]取分组数据,返回的是整个分组的DataFrame,赋值时会出现长度不匹配的问题,无法正确生成列表。
正确实现方法
推荐使用Pandas的分组操作(groupby+transform),避免低效循环,同时保证逻辑正确性:
方法一:分步实现
import pandas as pd # 构造原始DataFrame df = pd.DataFrame({ 'id': ['a', 'a', 'b', 'b', 'c', 'c', 'd', 'd'], 'item': ['tire', 'brick', 'wheel', 'brick', 'ice', 'brick', 'brick', 'grass'], 'val': [5, 5, 9, 6, 6, 3, 3, 6] }) # 按id分组,提取每组中item为brick的val值 brick_vals = df.groupby('id').apply( lambda group: group.loc[group['item'] == 'brick', 'val'].iloc[0] ) # 将每组的brick值映射回原DataFrame,计算比值 df['per/brick'] = brick_vals[df['id']].values / df['val'] # 保留一位小数,与期望结果格式对齐 df['per/brick'] = df['per/brick'].round(1) print(df)
方法二:简洁的transform写法
import pandas as pd df = pd.DataFrame({ 'id': ['a', 'a', 'b', 'b', 'c', 'c', 'd', 'd'], 'item': ['tire', 'brick', 'wheel', 'brick', 'ice', 'brick', 'brick', 'grass'], 'val': [5, 5, 9, 6, 6, 3, 3, 6] }) # 用transform直接在分组内计算比值 df['per/brick'] = df.groupby('id').apply( lambda g: g['val'].apply(lambda x: g.loc[g['item'] == 'brick', 'val'].iloc[0] / x) ).explode().astype(float).round(1) print(df)
结果说明
- 两种方法都能正确生成
per/brick列:brick自身的行比值为1(因为自身除以自身),其他item的行则是同组brick的val除以当前item的val。 - 使用Pandas原生分组操作比循环效率更高,尤其在数据量较大时优势明显。
内容的提问来源于stack exchange,提问作者ACan
相关产品推荐
相关产品推荐

