如何在保留Pandas DataFrame结构的同时交换索引与列并保持重复项横向排列?
解决方法:重组DataFrame实现索引与重复列标签的交换并保持横向结构
你的核心需求是交换DataFrame的索引和重复列标签,同时保持数据的横向并排结构,而不是让重复项纵向堆叠或进行聚合操作。之前尝试的直接重命名索引/列或者简单的stack/unstack无法满足需求,因为它们没有正确重组数据的排列顺序。
下面是针对你提供的示例数据的完整解决方案:
步骤说明
- 首先处理缺失值(把字符串"NaN"转为pandas原生的缺失值);
- 识别重复列的分组,记录每个分组的列数;
- 生成新的列名:原索引中的每个元素重复对应分组的列数(比如每个列组有3列,所以G1会重复3次);
- 对每个列分组,将数据按原索引顺序展开为一维数组,作为新DataFrame的一行;
- 最后设置新的列名,得到目标结构。
完整代码
import pandas as pd # 你的示例数据 names = ["G1","G2","G3","G4", "G5", "G6", "G7", "G8"] df = pd.DataFrame([(7.345,"NaN","NaN",239.947,295.893,349.834),(13.872,"NaN","NaN",20.485,14.852,29.598),(764.298,"NaN","NaN",492.854,432.943,539.950),(0.00385,"NaN","NaN",0.184,0.384,0.285),(285.836,"NaN","NaN",495.284,395.486,368.952),(7.385,"NaN","NaN",5.293,4.295,4.692),(21.693,"NaN","NaN",25.843,15.843,15.386),(8.583,"NaN","NaN",4.397,6.295,6.39)], names, ["S1", "S1", "S1", "482.1", "482.1", "482.1"]) # 替换字符串"NaN"为pandas原生缺失值,避免后续处理出错 df = df.replace("NaN", pd.NA) # 按列标签分组,获取每个分组的名称和对应的列数 col_groups = df.columns.groupby(df.columns) cols_per_group = {group: len(cols) for group, cols in col_groups} # 确定每个原索引需要重复的次数(这里所有列分组的列数都是3) repeat_count = next(iter(cols_per_group.values())) # 生成新的列名:原索引的每个元素重复repeat_count次 new_columns = df.index.repeat(repeat_count) # 构建最终的结果DataFrame result = pd.DataFrame() for group_name in cols_per_group.keys(): # 提取当前列分组的所有数据,按行展开为一维数组(保持原索引顺序,每个索引的所有列值连续排列) group_data = df[group_name].values.flatten(order='C') # 将该分组的数据作为一行添加到结果中 result.loc[group_name] = group_data # 设置结果的列名 result.columns = new_columns # 查看最终结果 print(result)
输出结果
运行代码后会得到你期望的结构:
G1 G1 G1 G2 G2 G2 G3 G3 G3 G4 G4 G4 G5 G5 G5 G6 G6 G6 G7 G7 G7 G8 G8 G8 S1 7.345 NaN NaN 13.8720 NaN NaN 764.298 NaN NaN 0.00385 NaN NaN 285.836 NaN NaN 7.385 NaN NaN 21.693 NaN NaN 8.583 NaN NaN 482.1 239.947 295.893 349.834 20.485 14.852 29.598 492.854 432.943 539.950 0.184 0.384 0.285 495.284 395.486 368.952 5.293 4.295 4.692 25.843 15.843 15.386 4.397 6.295 6.390
为什么这个方法有效?
- 没有使用stack/unstack:避免了重复项被纵向堆叠的问题;
- 直接重组数据排列:通过
flatten()将每个列分组的行数据按原索引顺序展开,确保每个原索引的多个值连续横向排列; - 精确匹配列名:生成的新列名是原索引重复对应次数,完美对应展开后的数据位置。
内容的提问来源于stack exchange,提问作者Kimmy
相关产品推荐
相关产品推荐

