问题描述
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
但是我不确定如何最好地解决这个问题,我尝试过stack
和pivot
,但是两者都将返回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'])
非常感谢您的帮助!
解决方法
您实际上在一个数据帧中有两组数据。再加上答案没有针对的问题
- 使用
np.where
和fillna()
的组合针对每个答案提出问题 - 只有答案索引,因此转置才有意义
-
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