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

如何在Pandas中基于分组双条件创建off-on差值列?

问题描述

我有一个包含受试者(subject)、两种状态(condition)及多个数值列的Pandas DataFrame,示例数据如下:

d = {
     "subject": [1, 1, 2, 2], 
     "condition": ["on", "off", "on", "off"], 
     "value": [1, 2, 3, 5]
     }
df = pd.DataFrame(data=d)

对应的表格:

subjectconditionvalue
01on1
11off2
22on3
32off5

希望新增一列off-on,表示同一受试者的off状态value值减去on状态value值的差值,预期结果如下:

subjectconditionvalueoff-on
01on11
11off21
22on32
32off52

目前用循环实现但效率低下:

onoff = (df[df.condition == "off"].value.reset_index() - df[df.condition == "on"].value.reset_index()).value
for idx, sub in enumerate(df.subject.unique()):
    df.loc[df.subject == sub, "off-on"] = onoff.iloc[idx]

需要无循环的高效解决方案。

高效解决方案

方法1:使用pivot + merge

先将数据按subject行转置,计算差值后再合并回原表,逻辑直观,支持多数值列批量计算:

# 转置得到每个subject的on和off值
pivot_df = df.pivot(index='subject', columns='condition', values='value').reset_index()
# 计算差值
pivot_df['off-on'] = pivot_df['off'] - pivot_df['on']
# 合并回原DataFrame
df = df.merge(pivot_df[['subject', 'off-on']], on='subject', how='left')

如果有多个数值列,只需将values参数改为列名列表(如values=['value1', 'value2']),即可批量生成对应的差值列。

方法2:使用groupby + transform

利用分组变换直接为每个组添加差值,无需额外合并,自动保持原表结构:

df['off-on'] = df.groupby('subject').apply(
    lambda x: x.loc[x['condition'] == 'off', 'value'].iloc[0] - x.loc[x['condition'] == 'on', 'value'].iloc[0]
).reindex(df['subject']).values

或者封装成更可读的函数形式:

def calc_off_on(group):
    off_val = group[group['condition'] == 'off']['value'].iloc[0]
    on_val = group[group['condition'] == 'on']['value'].iloc[0]
    return off_val - on_val

df['off-on'] = df.groupby('subject').apply(calc_off_on).reindex(df['subject']).values

方法3:使用unstack构建映射字典

先通过分组unstack得到差值映射,再用map快速匹配到原表,代码最简洁:

# 构建subject到差值的映射字典
diff_map = df.set_index(['subject', 'condition'])['value'].unstack().eval('off - on').to_dict()
# 映射到原表
df['off-on'] = df['subject'].map(diff_map)

该方法适合数据规整的场景(确保每个subject都有且仅有on、off两种状态)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 03:25:19