如何使用Python对pandas DataFrame仅针对门店列实现Unpivot逆透视
Pandas 门店库存列逆透视高效实现方案
你完全不需要走先全量逆透视再回转的流程,用pandas内置的wide_to_long函数就能一步完成转换,这是目前性能最高、代码最简洁的实现方式,适配你的列名结构。
实现代码
首先构造和你结构一致的示例数据方便测试:
import pandas as pd # 示例原始DataFrame,和你的列结构完全一致 df = pd.DataFrame({ 'Items': ['商品A', '商品B'], 'Description': ['测试商品A', '测试商品B'], 'Store 1 Qty': [10, 20], 'Store 1 Value': [100, 300], 'Store 2 Qty': [15, 25], 'Store 2 Value': [150, 375] })
方案1:wide_to_long实现(推荐,性能最高)
# 先调整列名格式,适配wide_to_long的参数要求 df.columns = df.columns.str.replace(r'Store (\d+) (Qty|Value)', r'\2_Store\1', regex=True) # 一步完成宽表转长表 result = pd.wide_to_long( df, stubnames=['Qty', 'Value'], # 需要生成的两个值列前缀 i=['Items', 'Description'], # 不需要转换的固定ID列 j='Store number', # 生成的门店编号列的名称 sep='_Store', # 值列前缀和门店编号之间的分隔符 suffix=r'\d+' # 门店编号的匹配规则:纯数字 ).reset_index()
输出的result就是你需要的结构:列包含Items、Description、Store number、Qty、Value,每个门店对应单独一行。
方案2:melt + pivot实现(兼容更多自定义列名场景)
如果你不想提前修改列名,也可以用melt拆分后再回转,性能稍低于方案1,但逻辑更直观:
# 先把门店相关列逆透视为长表 result = df.melt(id_vars=['Items', 'Description'], var_name='temp_col', value_name='val') # 从临时列拆分出门店编号和度量类型 result[['Store number', 'measure']] = result['temp_col'].str.extract(r'Store (\d+) (Qty|Value)') # 回转得到Qty和Value列 result = result.pivot( index=['Items', 'Description', 'Store number'], columns='measure', values='val' ).reset_index().rename_axis(columns=None)
两种方案都能直接得到你要的结果,10万行以内的数据集执行耗时都在毫秒级,效率远高于先全逆透视再回转的实现。
内容的提问来源于stack exchange,提问作者Alexander Tverdohleb
相关产品推荐
相关产品推荐

