如何以更Pythonic的方式重塑Pandas DataFrame并自动生成目标格式的列名?
如何以更Pythonic的方式重塑Pandas DataFrame并自动生成目标格式的列名?
嘿,你的思路其实没问题,但手动写列名确实有点麻烦,而且依赖固定切片的逻辑也不够健壮。我来给你几个更Pythonic的方案,既能自动生成目标列名,又能高效完成重塑,扩展性也更强~
方案一:用set_index + stack + 索引层级操作(最简洁)
这个方案利用Pandas的多层索引特性,完全基于数据的逻辑结构处理,不需要手动指定任何列名,代码也非常简洁:
import pandas as pd # 你的原始数据 df = pd.DataFrame({ 'TYPE': ['IN', 'OUT'], 'A': [550, 340], 'B': [350, 270], 'C': [600, 420], 'D': [360, 190] }) # 核心逻辑:设置索引 -> 堆叠列 -> 交换索引层级 -> 排序 -> 转成单行DataFrame -> 自动生成列名 result = (df.set_index('TYPE') # 把TYPE设为行索引 .stack() # 把A/B/C/D列堆叠成内层索引,得到多层索引的Series .swaplevel(0, 1) # 交换索引层级,让原列名(A/B/C/D)在第一层,TYPE(IN/OUT)在第二层 .sort_index() # 按列名排序,保证AIN/AOUT、BIN/BOUT的顺序 .to_frame().T # 转成单行的DataFrame .rename_axis(None, axis=0) # 去掉无关的行索引 ) # 自动生成列名:原列名 + TYPE(比如A+IN=AIN,A+OUT=AOUT) result.columns = [f'{col}{typ}' for col, typ in result.columns] print(result)
运行后会得到完全符合你需求的结果:
AIN AOUT BIN BOUT CIN COUT DIN DOUT 0 550 340 350 270 600 420 360 190
方案二:用melt + pivot的组合(更直观的逻辑)
如果你更习惯用melt的思路,也可以用这个方案,逻辑更贴近你原来的想法,但完全自动化:
result = (df.melt(id_vars='TYPE', var_name='col') # 保留TYPE作为标识,把A/B/C/D转成列值 .pivot(index='col', columns='TYPE', values='value') # 把TYPE转成列,得到列名对应IN/OUT的表格 .unstack() # 把多层结构展开成Series .swaplevel(0, 1) # 调整索引层级顺序 .sort_index() .to_frame().T .rename_axis(None, axis=0) ) result.columns = [f'{col}{typ}' for col, typ in result.columns] print(result)
为什么这些方法更Pythonic?
- 完全自动化:不管你后续增加多少列(比如E、F),代码都能自动生成对应的EIN/EOUT、FIN/FOUT列名,不需要手动修改
- 健壮性强:不依赖固定的切片位置(比如你原来的
iloc[1:,2:]),完全基于数据的逻辑结构处理,数据结构变化时不容易出错 - 链式调用:用Pandas的方法链(method chaining)写代码,逻辑清晰,可读性高,符合Python的简洁风格
- 扩展性好:如果后续TYPE的取值变化(比如增加'IN2'/'OUT2'),只需要调整列名生成的逻辑即可,核心重塑代码不需要改动
备注:内容来源于stack exchange,提问作者Sun Jar
相关产品推荐
相关产品推荐

