wide_to_long
通常很有用。该函数会自动提取后缀(您可以使用正则表达式指定确切的格式)。
假设这个例子:
id value1 value2 group1 group2
0 1 5 9 13 17
1 2 6 10 14 18
2 3 7 11 15 19
3 4 8 12 16 20
您可以运行:
pd.wide_to_long(df, stubnames=['value', 'group'], i='id', j='type')
输出:
value group
id type
1 1 5 13
2 1 6 14
3 1 7 15
4 1 8 16
1 2 9 17
2 2 10 18
3 2 11 19
4 2 12 20
实际上,文档中将其描述为“ 比 melt 更不灵活,但更加用户友好” 。
melt
处于较低水平,您需要对输出进行后处理,从:
df.melt(['id'])
输出:
id variable value
0 1 value1 5
1 2 value1 6
2 3 value1 7
3 4 value1 8
4 1 value2 9
5 2 value2 10
6 3 value2 11
7 4 value2 12
8 1 group1 13
9 2 group1 14
10 3 group1 15
11 4 group1 16
12 1 group2 17
13 2 group2 18
14 3 group2 19
15 4 group2 20
到:
tmp = df.melt(['id'])
tmp2 = tmp['variable'].str.extract('(\D+)(\d+)')
(tmp.assign(col=tmp2[0], type=tmp2[1])
.pivot(index=['id', 'type'], columns='col', values='value')
.rename_axis(columns=None)
)
输出:
group value
id type
1 1 13 5
2 17 9
2 1 14 6
2 18 10
3 1 15 7
2 19 11
4 1 16 8
2 20 12
请注意,您还可以使用 MultiIndex 重塑:
out = (df.set_index('id')
.pipe(lambda d: d.set_axis(pd.MultiIndex.from_frame(
d.columns.str.extract('(\D+)(\d+)'),
names=[None, 'type']), axis=1))
.stack()
)