以宽格式制作 pandas df 并将值取消连接到不同的列
Posted
技术标签:
【中文标题】以宽格式制作 pandas df 并将值取消连接到不同的列【英文标题】:Make pandas df in wide format and unconcatenate values to different columns 【发布时间】:2020-01-22 17:47:30 【问题描述】:抱歉,我在标题中解释问题时有点麻烦
我们偶然将 Pandas 数据框转为以下内容:
df = pd.DataFrame(np.array([[1,1,2], [1,2,1], [2,1,2], [2,2,2],[3,1,3]]),columns=['id', '3s', 'score'])
id 3s score
1 1 2
1 2 1
2 1 2
2 2 2
3 1 3
但是我们需要取消堆叠,所以 df 看起来像这样(原始版本):“3s”列“unpivots”到由 3 个具有 0 和 1 的有序列按顺序相加的离散集。因此,如果我们有'3s'= 2
和'score'= 2
,则对应的id
列['4','5','6']
(第二组3s)中的值将是[1,1,0]
(3 个中的2 个)
df2 = pd.DataFrame(np.array([[1,1,1,0,1,0,0], [2,1,1,0,1,1,0], [3,1,1,1,np.nan,np.nan,np.nan] ]),columns=['id', '1', '2','3','4','5','6'])
id 1 2 3 4 5 6
1 1 1 0 1 0 0
2 1 1 0 1 1 0
3 1 1 1
非常感谢任何帮助! (请救救我)
【问题讨论】:
【参考方案1】:用途:
n = 3
df2 = df.reindex(index = df.index.repeat(n))
new_df = (df2.assign(score = df2['score'].gt(df2.groupby(['id','3s'])
.id
.cumcount())
.astype(int),
columns = df2.groupby('id').cumcount().add(1))
.pivot_table(index = 'id',
values='score',
columns = 'columns',
fill_value = '')
.rename_axis(columns = None)
.reset_index())
print(new_df)
输出
id 1 2 3 4 5 6
0 1 1.0 1.0 0.0 1 0 0
1 2 1.0 1.0 0.0 1 1 0
2 3 1.0 1.0 1.0
如果您愿意,可以使用 fill_value = 0
id 1 2 3 4 5 6
0 1 1 1 0 1 0 0
1 2 1 1 0 1 1 0
2 3 1 1 1 0 0 0
【讨论】:
谢谢!快如闪电,但不知何故我得到了 400 列 :)【参考方案2】:这应该可以解决问题:
for gr in df.groupby('3s').groups:
for i in range(1,4):
df[str(i+(gr-1)*3)]=np.where((df['3s'].eq(gr))&(df['score'].ge(i)), 1,0)
df=df.drop(['3s', 'score'], axis=1).groupby('id').max().reset_index()
输出:
id 1 2 3 4 5 6
0 1 1 1 0 1 0 0
1 2 1 1 0 1 1 0
2 3 1 1 1 0 0 0
【讨论】:
谢谢,更稳定的解决方案!以上是关于以宽格式制作 pandas df 并将值取消连接到不同的列的主要内容,如果未能解决你的问题,请参考以下文章
Pandas 循环数据框并将所有行与其他 DF 行进行比较并分配一个值
在 column1 中查找确切的单元格值并将 column2 的值连接到新列中
在 column1 中查找确切的单元格值并将 column2 的值连接到新列中