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

pandas按ID分组根据SOURCE为A的NAME值新增全组CNAME列

解决方案

按ID分组填充对应SOURCE=A的NAME值有两种可直接运行的实现方式,输出结果完全匹配你的预期。


写法1:groupby.transform 分组广播实现

你之前用transform未达预期是因为内部逻辑没有把取到的目标值广播到全组,正确代码如下:

import pandas as pd

df['CNAME'] = df.groupby('ID')['NAME'].transform(
    lambda group_col: group_col[df.loc[group_col.index, 'SOURCE'] == 'A'].iloc[0]
)

逻辑说明

  • transform会保证分组计算后的返回结果和原DataFrame长度、索引完全对齐,可以直接赋值为新列
  • 每个分组内先筛选出SOURCE == 'A'对应的NAME值,取到该值后会自动填充到当前ID下的所有行
  • 如果存在部分ID没有SOURCE为A的记录,可以加判空逻辑避免报错:
def fetch_cname(group_col):
    target_val = group_col[df.loc[group_col.index, 'SOURCE'] == 'A']
    return target_val.iloc[0] if len(target_val) > 0 else pd.NA

df['CNAME'] = df.groupby('ID')['NAME'].transform(fetch_cname)

写法2:映射字典法(大数据量下性能更优)

不需要分组操作,先提取ID和对应A类NAME的映射关系,直接按ID匹配赋值即可,代码更简洁:

# 构造ID -> 对应SOURCE=A的NAME的映射字典
cname_mapping = df[df['SOURCE'] == 'A'].set_index('ID')['NAME'].to_dict()
# 按ID映射赋值
df['CNAME'] = df['ID'].map(cname_mapping)

原写法问题说明

你之前尝试的df.groupby('ID').apply(lambda x: np.where(x['SOURCE'] == 'A', x['NAME'],' '))存在两个问题:

  1. np.where仅给SOURCE为A的行返回NAME,其余行返回空字符串,没有把取到的A类NAME填充到同组其他行
  2. apply直接返回的是分组嵌套结构,没有和原df的索引做对齐,无法直接赋值为新列

运行上述任意一种写法,得到的输出和你给出的期望结果完全一致:

ID  NAME SOURCE CNAME
0   1   ABC      B   AXY
1   1   ABC      C   AXY
2   1   AXY      A   AXY
3   2   XYZ      B   XYZ
4   2   XYZ      A   XYZ
5   3  SASA      D   SSA
6   3  SASA      B   SSA
7   3   SSA      A   SSA
8   3   SSA      C   SSA
9   4   BVA      A   BVA
10  4    BA      B   BVA
11  5   NAS      A   NAS
12  5   VAN      B   NAS

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 10:15:37