使用堆栈/堆栈重塑数据框

问题描述

我有一个看起来像这样的数据框:

df1 = pd.DataFrame({'Type' : ['Q','A','A'],'Fields': ['Q1','Pre','Post'],'ChildA' : [0,3,5],'ChildB' : [0,2,3]})

    ChildA  ChildB Fields Field_Type
 0       0       0     Q1          Q
 1       3       2    Pre          A
 2       5       3   Post          A

总共有大约200个孩子和大约50个问题。我想要达到的目标是这样的:

      Name     Question    Pre     Post
   0  ChildA   Q1          3       5
   1  ChildB   Q1          2       3
   2  ChildA   Q2          1       4
   3  ChildB   Q2          3       3

但是我不确定如何最好地解决这个问题,我尝试过stackpivot,但是两者都将返回ValueError: Index contains duplicate entries,cannot reshape,或者当它起作用时,它的格式不是我需要或可以朝着正确的格式努力。到目前为止,我最接近的方法是使用转置df2 = df1[0:3].T,只要我一次处理3行,它就可以正常工作,但这似乎效率很低,而且我知道使用枢轴或堆栈/取消堆叠。

也许这会涉及一些索引,所以我被stack吸引住了,因为pivot在我尝试说出诸如Exception: Data must be 1-dimensional之类的各种问题时>

df1.pivot(columns='Name',values=['Ben','Jack'])

非常感谢您的帮助!

解决方法

您实际上在一个数据帧中有两组数据。再加上答案没有针对的问题

  1. 使用np.wherefillna()的组合针对每个答案提出问题
  2. 只有答案索引,因此转置才有意义
  3. stack() 问题重新成为专栏
import numpy as np
df1 = pd.DataFrame({'Type' : ['Q','A','A'],'Fields': ['Q1','Pre','Post'],'ChildA' : [0,3,5],'ChildB' : [0,2,3]})

maskq = df1["Type"]=="Q"
# need to get question against each answer
df1 = (df1
 .assign(Question=lambda x: np.where(x["Type"]=="Q",x["Fields"],np.nan))
 .assign(Question=lambda x: x["Question"].fillna(method="ffill"))
)
# now take just questions and organise as required
df1 = df1.loc[~maskq,[c for c in df1.columns if c!="Type"]].set_index(["Fields","Question"]).T.stack()

输出

Fields           Post  Pre
       Question           
ChildA Q1           5    3
ChildB Q1           3    2