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

Python Pandas实现DataFrame转置与分组:ID-STORE-PUSH格式转多STORE列宽表的问题求助

解决DataFrame长转宽并合并的问题

嘿,我一眼就看出问题所在啦——你当前的代码里,groupby('PNO')['Push'].transform()没有针对每个目标门店做筛选逻辑,所以分组后返回的是整个PNO组的默认聚合值(比如均值),自然所有新列的结果都一模一样。

下面给你两种靠谱的解决方案,推荐第一种,简洁高效:

方法一:用pivot_table生成宽表后合并(推荐)

这种方式是Pandas处理长表转宽表的标准做法,一步生成所有需要的门店列,再和原表合并:

# 1. 生成宽表:将STORE转为列,PUSH作为对应列的值
wide_store_df = combined_sf2.pivot_table(
    index='PNO',  # 你的ID列
    columns='STORE',  # 要转成列的门店字段
    values='Push',  # 要填充的数值字段
    aggfunc='first'  # 如果同一个PNO+STORE有多条记录,用first取第一条,也可以用mean/median等聚合
).reset_index()

# 2. 调整列名格式为你需要的大写形式,并只保留指定的7个门店
required_stores = ['adh', 'ayc', 'maeg', 'rot', 'witz', 'mar', 'bud']
# 重命名列,把门店名转成大写
wide_store_df.columns = ['PNO'] + [store.upper() for store in wide_store_df.columns if store != 'PNO']
# 只保留需要的列
wide_store_df = wide_store_df[['PNO'] + [s.upper() for s in required_stores]]

# 3. 合并到原DataFrame,用PNO做关联键,左连接保留原表所有行
df = df.merge(wide_store_df, on='PNO', how='left')

方法二:逐列用transform生成(适合特殊场景)

如果你一定要用transform的方式逐列生成,需要在transform里加入门店筛选的逻辑,确保只取当前门店的Push值:

required_stores = {'adh': 'ADH', 'ayc': 'AYC', 'maeg': 'MAEG', 
                   'rot': 'ROT', 'witz': 'WITZ', 'mar': 'MAR', 'bud': 'BUD'}

for store, col_name in required_stores.items():
    df[col_name] = combined_sf2.groupby('PNO')['Push'].transform(
        lambda x: x[combined_sf2.loc[x.index, 'STORE'] == store].iloc[0] 
        if any(combined_sf2.loc[x.index, 'STORE'] == store) 
        else None  # 如果该PNO没有这个门店,填充None
    )

关键说明

  • 原代码的问题核心:没有针对每个门店筛选数据,groupby后直接transform会返回整个分组的聚合结果(默认是mean),所以所有列值相同。
  • 方法一的优势:代码简洁、执行效率高,尤其是数据量较大时,比逐列transform快很多。
  • 如果同一个PNO+STORE存在多条记录,记得调整aggfunc参数,比如用sum求和、mean取平均,根据你的业务需求来定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 14:42:45