如何使用Pandas重塑/堆叠两列数据?
Pandas 重塑周度销售数据:宽表转长表 + 重复列名处理
嘿,我来帮你搞定这个Pandas数据重塑的问题,还有你提到的重复列名疑问~
首先,先明确你的核心需求:把宽表结构(每个产品一行,多列对应不同周的销售和单位)转换成长表结构(每个产品每周一行,对应该周的销售与单位)。下面分步骤给你解决方法:
一、先处理重复列名的问题
你提到用read_csv读取时,重复列名被自动命名为.1,这个是Pandas的默认行为,本身没有问题——它只是用来区分重复列名,避免列名冲突。但为了后续数据处理更清晰,建议手动把这些列名改成有意义的名称(比如给销售列加_Sales后缀,单位列加_Units后缀)。
处理方式两种:
- 读取CSV时直接指定列名(如果你知道原始列的含义):
import pandas as pd # 自定义列名,明确区分销售和单位 col_names = [ 'Product', 'Desc1', 'Desc2', 'Desc3', 'Week1_Sales', 'Week2_Sales', 'Week3_Sales', 'Week1_Units', 'Week2_Units', 'Week3_Units' ] # 读取CSV,指定列名并把Product设为索引 df = pd.read_csv('your_data.csv', names=col_names, header=0, index_col='Product')
- 读取后重命名列:
如果已经读取了带.1后缀的数据,可以批量重命名:
# 假设原始列名是:Desc1, Desc2, Desc3, Week1, Week2, Week3, Week1.1, Week2.1, Week3.1 new_cols = ['Desc1', 'Desc2', 'Desc3'] # 处理销售列 new_cols += [f'{col}_Sales' for col in df.columns[3:6]] # 处理单位列(把.1替换成_Units) new_cols += [col.replace('.1', '_Units') for col in df.columns[6:]] # 赋值新列名 df.columns = new_cols
二、核心:宽表转长表(实现你期望的结果)
这里用Pandas的wide_to_long函数最方便,它专门针对这种「前缀+编号」的列名结构做重塑:
# 先把索引(Product)转回普通列,方便后续处理 df_reset = df.reset_index() # 使用wide_to_long转成长表 result = pd.wide_to_long( df_reset, stubnames=['Week_Sales', 'Week_Units'], # 列名的前缀部分 i=['Product', 'Desc1', 'Desc2', 'Desc3'], # 保持不变的列(行标识) j='Week', # 提取出的周编号,会变成新列 sep='_', # 前缀和编号之间的分隔符 suffix='\\d+' # 匹配编号的正则(这里是数字) ) # 重置索引,并重命名列成你想要的格式 final_result = result.reset_index().rename(columns={ 'Week_Sales': 'Sales (By Week)', 'Week_Units': 'Units (By Week)' })
运行后,final_result就完全符合你期望的结构:每个产品每周对应一行,包含描述列、当周销售和单位数据。
关于你尝试的多级索引方法
你之前的多级索引构建有小问题——iterables应该是两个层级的列表,而不是把所有列混在一起。如果想用多级索引实现,也可以这样做:
# 给原始列构建多级索引(区分Sales和Units层级) multi_cols = pd.MultiIndex.from_tuples([ ('Desc', 'Desc1'), ('Desc', 'Desc2'), ('Desc', 'Desc3'), ('Sales', 'Week1'), ('Sales', 'Week2'), ('Sales', 'Week3'), ('Units', 'Week1'), ('Units', 'Week2'), ('Units', 'Week3') ]) df.columns = multi_cols # 把Week层级从列转成行 result = df.stack(level=1).reset_index().rename(columns={'level_1': 'Week'})
但相比之下,wide_to_long更贴合你的数据结构,代码也更简洁。
内容的提问来源于stack exchange,提问作者Julian
相关产品推荐
相关产品推荐

