如何将Pandas DataFrame中的列块转换为堆叠行?
Pandas 将多组列块堆叠为行的实现方法
原始数据
import pandas as pd df = pd.DataFrame({ 'EID': [1001, 1002, 1003, 1004], 'FX1': ['FXA', 'FXB', 'FXC', 'FXD'], 'FY1': ['FYA', 'FYB', 'FYC', 'FYD'], 'FZ1': ['FZA', 'FZB', 'FZC', 'FZD'], 'SUB1': [101, 101, 101, 101], 'FX2': ['FXE', 'FXF', 'FXG', 'FXH'], 'FY2': ['FYE', 'FYF', 'FYG', 'FYH'], 'FZ2': ['FZE', 'FZF', 'FZG', 'FZH'], 'SUB2': [102, 102, 102, 102], 'FX3': ['FXI', 'FXJ', 'FXK', 'FXL'], 'FY3': ['FYI', 'FYJ', 'FYK', 'FYL'], 'FZ3': ['FZI', 'FZJ', 'FZK', 'FZL'], 'SUB3': [103, 103, 103, 103] })
目标格式
需要将每组FXn-FYn-FZn-SUBn列块转换为统一列名的行,最终得到包含EID、FX1、FY1、FZ1、SUB的长表。
方法一:使用pd.wide_to_long(推荐,适合列名有规律的场景)
这个函数专门处理宽表转长表,针对列名是「前缀+数字」的格式非常高效:
# 转换宽表为长表 result = pd.wide_to_long( df, stubnames=['FX', 'FY', 'FZ', 'SUB'], # 列名的前缀部分 i='EID', # 保留的标识列 j='num', # 提取的后缀数字,临时列 sep='' # 前缀和数字之间无分隔符 ) # 整理格式:重置索引、删除临时列、重命名列、排序 result = result.reset_index()\ .drop(columns='num')\ .rename(columns={'FX': 'FX1', 'FY': 'FY1', 'FZ': 'FZ1'})\ .sort_values('SUB')\ .reset_index(drop=True)
方法二:分组提取后合并(直观,适合列块数量少的场景)
如果列名规律不明显,或者需要更灵活的处理,可以直接提取每组列块,重命名后合并:
# 定义每组的列名列表 column_groups = [ ['EID', 'FX1', 'FY1', 'FZ1', 'SUB1'], ['EID', 'FX2', 'FY2', 'FZ2', 'SUB2'], ['EID', 'FX3', 'FY3', 'FZ3', 'SUB3'] ] # 遍历每组,提取并重命名列 processed_dfs = [] for cols in column_groups: temp_df = df[cols].rename(columns={ cols[1]: 'FX1', cols[2]: 'FY1', cols[3]: 'FZ1', cols[4]: 'SUB' }) processed_dfs.append(temp_df) # 合并所有处理后的子表 result = pd.concat(processed_dfs, ignore_index=True)
最终结果
两种方法都能得到符合要求的DataFrame,输出示例:
EID FX1 FY1 FZ1 SUB 0 1001 FXA FYA FZA 101 1 1002 FXB FYB FZB 101 2 1003 FXC FYC FZC 101 3 1004 FXD FYD FZD 101 4 1001 FXE FYE FZE 102 5 1002 FXF FYF FZF 102 6 1003 FXG FYG FZG 102 7 1004 FXH FYH FZH 102 8 1001 FXI FYI FZI 103 9 1002 FXJ FYJ FZJ 103 10 1003 FXK FYK FZK 103 11 1004 FXL FYL FZL 103
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

