Groupby并在熊猫,Python中转置


问题内容

数据框有

ID  col  col2   col3   col4

1   A    50      S      1
1   A    52      M      4
1   B    45      N      8
1   C    18      S      7

想要数据框

ID  col  colA   colB   colC   colD   colE   colF

1   A    50     52      S      M       1      4
1   B    45     NULL    N     NULL     8     NULL
1   C    18     NULL    S     NULL     7     NULL

我想要每个唯一ID + col(groupby ID和col)一行。如果每个ID +
col有多个条目(最大值不能为2,则不能再增加),然后将col2的第一个值放入colA并将第二个值放入colB,将col3的第一个值放入colC和第二个值在colD中,然后将第一个colE中的col4值和colF中的第二个值。如果每个ID
+ col只有一个条目,那么对于col2,将值放入colA,而colB为null等。

我尝试首先创建一个计数器:

df['COUNT'] = df.groupby(['ID','col']).cumcount()+1

从这里开始,我想添加一个专栏说

if count=1 then df['colA']=df.col2
if count=2 then df['colB']=df.col2

..但这仍将导致与原始df相同的行数。


问题答案:

我认为需要set_indexunstack

df['COUNT'] = df.groupby(['ID','col']).cumcount()+1

df = df.set_index(['ID','col', 'COUNT'])['col2'].unstack().add_prefix('col').reset_index()
print (df)
COUNT  ID col  col1  col2
0       1   A  50.0  52.0
1       1   B  45.0   NaN
2       1   C  18.0   NaN

要么:

c = df.groupby(['ID','col']).cumcount()+1

df = df.set_index(['ID','col', c])['col2'].unstack().add_prefix('col').reset_index()
print (df)
   ID col  col1  col2
0   1   A  50.0  52.0
1   1   B  45.0   NaN
2   1   C  18.0   NaN

编辑:

对于多列,解决方案有所更改,因为在MultiIndexin列中进行处理:

df['COUNT'] = (df.groupby(['ID','col']).cumcount()+1).astype(str)

#remove col2
df = df.set_index(['ID','col', 'COUNT']).unstack()
#flatten Multiindex
df.columns = df.columns.map('_'.join)
df = df.reset_index()
print (df)
   ID col  col2_1  col2_2 col3_1 col3_2  col4_1  col4_2
0   1   A    50.0    52.0      S      M     1.0     4.0
1   1   B    45.0     NaN      N   None     8.0     NaN
2   1   C    18.0     NaN      S   None     7.0     NaN