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
相关产品推荐
相关产品推荐

