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

Pandas避免合并操作:按#PROD和#CURRENCY分组填充TP字段

问题与解决方案

问题描述

现有如下结构的DataFrame:

import pandas as pd
data=[['Offshore','NY','A','USD','ABC_USD'],['Onshore','BH','A','USD',''],                  
      ['Onshore','AE','A','USD',''],['Offshore','NY','A','GBP','GBP_ABC'],['Onshore','BH','A','GBP',''],                           
      ['Onshore','AE','A','GBP',''],['Onshore','BH','A','EUR',''],['Onshore','AE','A','EUR','']]

df = pd.DataFrame(data, columns=['Loc', 'Country','#PROD','#CURRENCY','TP'])

需求:按#PROD和#CURRENCY字段分组,将Loc列为Onshore的行的TP字段替换为同组内Offshore行的TP值,要求无需创建两个DataFrame再进行连接。目前已通过拆分再连接的方式实现,希望得到更简洁的实现方法。

简洁实现方式

以下几种方法均可在原DataFrame上直接完成操作,无需拆分连接:

方法1:用groupby.transform提取分组内Offshore的TP值

适用于每组最多只有一条Offshore行的场景:

df['TP'] = df.groupby(['#PROD', '#CURRENCY']).apply(
    lambda g: g['TP'].mask(g['Loc'] == 'Onshore', g[g['Loc'] == 'Offshore']['TP'].iloc[0] if not g[g['Loc'] == 'Offshore'].empty else g['TP'])
).reset_index(drop=True)

方法2:结合mask与groupby.transform简化填充

先将Onshore行的TP标记为空,再用分组内的第一个非空TP值填充(需确保Offshore行的TP是组内唯一非空值):

# 将Onshore行的TP转为NaN,再用分组内的第一个有效值填充
df['TP'] = df['TP'].mask(df['Loc'] == 'Onshore').groupby([df['#PROD'], df['#CURRENCY']]).transform('first')

方法3:鲁棒性兼容(处理无Offshore行的分组)

如果存在分组没有Offshore行(如示例中的EUR组),可保留原空值,逻辑更通用:

def fill_onshore_tp(group):
    offshore_records = group[group['Loc'] == 'Offshore']
    if not offshore_records.empty:
        # 取Offshore行的TP值,覆盖同组所有行的TP
        group['TP'] = offshore_records['TP'].iloc[0]
    return group

# 应用分组逻辑,不保留分组键索引
df = df.groupby(['#PROD', '#CURRENCY'], group_keys=False).apply(fill_onshore_tp)

执行效果

所有Onshore行的TP会被替换为同组Offshore行的TP值;无Offshore行的分组则保持原空值,完全符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 08:57:23