You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas:如何将列设为索引并保留原索引重复结构转换DataFrame

问题描述

现有如下结构的Pandas DataFrame:

import pandas as pd

dft = pd.DataFrame({1: [0.1,0.4,0.2,0.5],2:[0.4,0.5,0.3,0.4],3:[0.2,0.4,0.6,0.7]}, index=['t1', 't1','t2','t2'])
dft.index.name = "tt"
dft.columns.name='num'

对应的表格形态:

num123
tt
t10.10.40.2
t10.40.50.4
t20.20.30.6
t20.50.40.7

需要将其转换为如下结构的DataFrame:

ttt1t2
num
10.10.2
10.40.5
20.40.3
20.50.4
30.20.6
30.40.7
解决方案

可以通过分组标识、重塑索引的组合操作实现,这里提供两种简洁的实现方式:

方式一:链式pivot操作

import pandas as pd

dft = pd.DataFrame({1: [0.1,0.4,0.2,0.5],2:[0.4,0.5,0.3,0.4],3:[0.2,0.4,0.6,0.7]}, index=['t1', 't1','t2','t2'])
dft.index.name = "tt"
dft.columns.name='num'

# 链式操作完成转换
result = (dft
          # 给同一tt下的行添加分组编号,区分重复行
          .assign(row_id=dft.groupby('tt').cumcount())
          # 将tt从索引转为列
          .reset_index()
          # 按num和row_id重塑,把tt的值转为列
          .pivot(index=['num', 'row_id'], columns='tt', values=[1,2,3])
          # 移除列的冗余层级
          .droplevel(0, axis=1)
          # 移除row_id索引
          .reset_index(level='row_id', drop=True)
          # 调整最终的索引和列顺序
          .reset_index()
          .set_index('num')[['t1', 't2']])

print(result)

方式二:melt+pivot组合操作

import pandas as pd

dft = pd.DataFrame({1: [0.1,0.4,0.2,0.5],2:[0.4,0.5,0.3,0.4],3:[0.2,0.4,0.6,0.7]}, index=['t1', 't1','t2','t2'])
dft.index.name = "tt"
dft.columns.name='num'

# 先将宽表转长表,再重塑为目标结构
result = (dft
          .reset_index()
          .melt(id_vars='tt', var_name='num', value_name='val')
          .assign(row_id=lambda x: x.groupby(['tt', 'num']).cumcount())
          .pivot(index=['num', 'row_id'], columns='tt', values='val')
          .reset_index(level='row_id', drop=True))

print(result)

两种方式执行后都会输出目标结构:

t1   t2
num         
1    0.1  0.2
1    0.4  0.5
2    0.4  0.3
2    0.5  0.4
3    0.2  0.6
3    0.4  0.7

内容的提问来源于stack exchange,提问作者anon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 00:11:21