Pandas - 将多级df中的纵向数据重组为单级列

时间:2015-11-04 17:27:37

标签: python pandas

尝试在4个不同类型的测试(测试A到D)中重新构建包含4个不同主题(主题1到4)的数据的df(6列),每个测试在其自己的列中进行4天(第1天到第4天)第四天)。

df= pd.DataFrame({'subject': [1, 2, 2, 3,4,1,1,2,3,2],
                  'test': ['A', 'B', 'C', 'D','A', 'B', 'C', 'D','B', 'C'],
                  'Day1': ['X1','X2','X3','X4','X5','X6','X7','X8','X9','X10'],
                  'Day2': ['Y1','Y2','Y3','Y4','Y5','Y6','Y7','Y8','Y9','Y10'],
                  'Day3': ['Z1','Z2','Z3','Z4','Z5','Z6','Z7','Z8','Z9','Z10'],
                  'Day4': ['K1','K2','K3','K4','K5','K6','K7','K8','K9','K10']})

我的DataFrame目前是什么样的:

enter image description here

为了分析我的数据,我想将其重组为单一的长格式“平面传播” - 其中每个主题只有一行包含所有观察结果。

理想的结构:

enter image description here

1 个答案:

答案 0 :(得分:1)

对于您提供的示例数据,这是不可能的,因为pandas索引(列和行标签)都不能包含重复项。您数据中的一个示例是Subject 2test C - 此组合出现两次,这意味着无法知道哪些值应与相应的日期一起出现。

如果您有唯一的列和行标签,则可以使用meltpivot的组合,如下所示:

import pandas as pd

df = pd.DataFrame({'subject': [1, 2, 2, 3,4,1,1,2,3,2],
                  'test': ['A', 'B', 'C', 'D','A', 'B', 'C', 'D','B', 'C'],
                  'Day1': ['X1','X2','X3','X4','X5','X6','X7','X8','X9','X10'],
                  'Day2': ['Y1','Y2','Y3','Y4','Y5','Y6','Y7','Y8','Y9','Y10'],
                  'Day3': ['Z1','Z2','Z3','Z4','Z5','Z6','Z7','Z8','Z9','Z10'],
                  'Day4': ['K1','K2','K3','K4','K5','K6','K7','K8','K9','K10']})

melted = pd.melt(df, id_vars=['subject', 'test'])

melted根据传递给它的id_vars重塑数据。它现在看起来像这样:

   subject test variable value
0        1    A     Day1    X1
1        2    B     Day1    X2
2        2    C     Day1    X3
3        3    D     Day1    X4
4        4    A     Day1    X5

现在,您可以创建一个包含要作为列标题的值的新列。 这些必须是唯一的。

melted['col_name'] = 'test' + melted['test'] + '-' + melted['variable']

现在melted具有适合我们想要成为长格式标题的值:

   subject test variable value    col_name
0        1    A     Day1    X1  testA-Day1
1        2    B     Day1    X2  testB-Day1
2        2    C     Day1    X3  testC-Day1
3        3    D     Day1    X4  testD-Day1
4        4    A     Day1    X5  testA-Day1

pivot让我们完成剩下的工作,但在这种情况下无效,因为标题不是唯一的(同样,Subject 2和{{的问题1}})。

test C

例如,如果melted.pivot('subject', columns='col_name', values='value') 行是时间戳,我们可能不会遇到此问题。