You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas中按组减去对应Empty的average值生成norm列

解决多层索引DataFrame按组减去Empty对应值的问题

问题描述

现有一个多层索引的DataFrame,需要为每个Chem+ID组内的所有记录,计算其average值与本组内Dose为Empty的average值的差值,生成新列norm。此前尝试用groupby取组内最小值的方法,但Empty对应的average并非所有组的最小值,因此该方法无效。

原数据

Chem ID  Dose     average
A    23  Control  0.45
         Empty    0.33
         Positive 0.55
         1mM      0.66
B    24  Control  0.67
         Empty    0.45
         Positive 0.80
         1mM      0.70
C    26  Control  0.66
         Empty    0.50
         Positive 0.78
         1mM      0.66
D    29  Control  0.54
         Empty    0.24
         Positive 0.33
         1mM      0.78
E    30  Control  0.66
         Empty    0.40
         Positive 0.76
         1mM      0.56
F    35  Control  0.67
         Empty    0.32
         Positive 0.43
         1mM      0.44

期望输出

Chem ID  Dose     average norm
A    23  Control  0.45    0.12
         Empty    0.33    0.00
         Positive 0.55    0.22
         1mM      0.66    0.33
B    24  Control  0.67    0.22
         Empty    0.45    0.00
         Positive 0.80    0.35
         1mM      0.70    0.25
C    26  Control  0.66    0.16
         Empty    0.50    0.00
         Positive 0.78    0.28
         1mM      0.66    0.16
D    29  Control  0.54    0.30
         Empty    0.24    0.00
         Positive 0.33    0.09
         1mM      0.78    0.54
E    30  Control  0.66    0.26
         Empty    0.40    0.00
         Positive 0.76    0.36
         1mM      0.56    0.16
F    35  Control  0.67    0.35
         Empty    0.32    0.00
         Positive 0.43    0.11
         1mM      0.44    0.12

解决方案

方法1:利用groupby.transform直接计算

通过groupby按Chem和ID分组,在每个组内精准定位Dose为Empty的average值,再让组内所有average减去该基准值:

# 若DataFrame已是多层索引(Chem、ID、Dose为索引)
df['norm'] = df.groupby(['Chem', 'ID'])['average'].transform(
    lambda x: x - x[x.index.get_level_values('Dose') == 'Empty'].iloc[0]
)

# 若原数据未设置多层索引,先执行以下步骤:
# df = df.set_index(['Chem', 'ID', 'Dose'])

方法2:提取基准值后合并计算

先单独提取每个Chem+ID组对应的Empty基准值,再通过合并将基准值匹配到原表的每条记录,最后计算差值:

# 提取Empty对应的average值,并重命名列
empty_baseline = df[df['Dose'] == 'Empty'][['Chem', 'ID', 'average']].rename(columns={'average': 'empty_avg'})

# 合并基准值到原表
df = df.merge(empty_baseline, on=['Chem', 'ID'], how='left')

# 计算norm列并清理临时列
df['norm'] = df['average'] - df['empty_avg']
df = df.drop(columns='empty_avg')

两种方法都能准确获取每个组的Empty基准值,避免了依赖组内最小值的局限性,最终得到符合要求的norm列。

内容的提问来源于stack exchange,提问作者cadillac_carlito

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 06:00:34