pandas - 使用 stack/unstack 重塑数据框
问题描述
我有一个看起来像这样的数据框:
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
推荐阅读
- python - python :- sublime 中用户问题的输入
- replace - 删除除 Notepad++ 中一行的前 3 个单词之外的所有内容
- java - 如何获取每行的最后一个索引?
- javascript - Html 文件和 css 实现无法在我的 chrome 浏览器上正确显示
- amazon-web-services - AWS Data Pipeline 中 EC2 资源的 AWS IAM 设置
- git - 推入空的 git repo 时“无法推送引用”
- css - Razor 类库中的 Blazor 组件(CSS 隔离)
- c++ - 在表1 Sqlit下附上table2
- mongodb - 查找部署了我的 MongoDB 的服务器的 IP 地址
- flutter - 来回动画不能在颤动中工作