这是我在StackOverflow的第一个问题。我希望你可以帮助解决一段时间困扰我的问题。我无法找到合适的答案。
我的数据如下:
df = pd.DataFrame({'col1': {0: 1, 1: 1, 2: 1},
'col2': {0: 1, 1: 2, 2: 3},
'col3': {0: 1, 1: 2, 2: 3},
'col4': {0: 1.1, 1: 2.1, 2: 3.1},
'col5': {0: 10, 1: 12, 2: 14},
'col6': {0: 1.2, 1: 2.2, 2: 3.2},
'col7': {0: 11, 1: 13, 2: 15},
})
df.columns = ["VZ", "NZ", "L", "T_0_Rel", "T_0_Abs", "T_Akt_Rel", "T_Akt_Abs"]
df
输出(没有索引列):
╔════╦════╦═══╦═════════╦═════════╦═══════════╦═══════════╗
║ VZ ║ NZ ║ L ║ T_0_Rel ║ T_0_Abs ║ T_Akt_Rel ║ T_Akt_Abs ║
╠════╬════╬═══╬═════════╬═════════╬═══════════╬═══════════╣
║ 1 ║ 1 ║ 1 ║ 1.1 ║ 10 ║ 1.2 ║ 11 ║
║ 1 ║ 1 ║ 2 ║ 2.1 ║ 12 ║ 2.2 ║ 13 ║
║ 1 ║ 1 ║ 3 ║ 3.1 ║ 14 ║ 3.2 ║ 15 ║
╚════╩════╩═══╩═════════╩═════════╩═══════════╩═══════════╝
现在我想把这个DataFrame扭曲成这样的东西:
╔════╦════╦═══╦═════════════╦═════╦═════╗
║ VZ ║ NZ ║ L ║ T_0 / T_Akt ║ Abs ║ Rel ║
╠════╬════╬═══╬═════════════╬═════╬═════╣
║ 1 ║ 1 ║ 1 ║ T_0 ║ 10 ║ 1.1 ║
║ 1 ║ 1 ║ 1 ║ T_Akt ║ 11 ║ 1.2 ║
║ 1 ║ 2 ║ 2 ║ T_0 ║ 12 ║ 2.1 ║
║ 1 ║ 2 ║ 2 ║ T_Akt ║ 13 ║ 2.2 ║
║ 1 ║ 3 ║ 3 ║ T_0 ║ 14 ║ 3.1 ║
║ 1 ║ 3 ║ 3 ║ T_Akt ║ 15 ║ 3.2 ║
╚════╩════╩═══╩═════════════╩═════╩═════╝
基本上,我希望每个T_O-和T_Akt值都有一行,而Abs-和Rel-值可以保持在一行。
我认为这应该可以通过 .stack()或 .melt()来实现,但我可以弄明白该怎么做。
我在这一切背后的意图是在我的DataFrame中使用色调 - 参数 seaborn.boxplot 或 .violinplot 功能。我无法弄清楚如何将hue-argument与几列而不是分类值一起使用。 (也许我在这里错了,有一种更简单的方法......)
非常感谢。
答案 0 :(得分:4)
由于您在概念上有一个分层列索引,我会这样做,然后使用stack
df = pandas.DataFrame({
'VZ': {0: 1, 1: 1, 2: 1},
'NZ': {0: 1, 1: 2, 2: 3},
'L': {0: 1, 1: 2, 2: 3},
'T_0_Rel': {0: 1.1, 1: 2.1, 2: 3.1},
'T_0_Abs': {0: 10, 1: 12, 2: 14},
'T_Akt_Rel': {0: 1.2, 1: 2.2, 2: 3.2},
'T_Akt_Abs': {0: 11, 1: 13, 2: 15},
})
print(
df.set_index(['VZ', 'NZ', 'L']) # row labels
.rename(columns=lambda c: tuple(c.rsplit('_', 1))) # create the multi-cols
.stack(level=0) # unpivot
.reset_index() # move the row labels back into normal columns
)
我明白了:
VZ NZ L level_3 Abs Rel
0 1 1 1 T_0 10 1.1
1 1 1 1 T_Akt 11 1.2
2 1 2 2 T_0 12 2.1
3 1 2 2 T_Akt 13 2.2
4 1 3 3 T_0 14 3.1
5 1 3 3 T_Akt 15 3.2