Groupby并在pandas中进行转置,python

时间:2018-05-15 14:03:23

标签: python pandas numpy

Dataframe有

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

Dataframe想要

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 1行(groupby ID和col)。 如果每个ID + col有多个条目(max可以是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相同的行数。

3 个答案:

答案 0 :(得分:2)

我认为set_index需要unstack

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

编辑:

对于多列,解决方案有点改变,因为在列中使用MultiIndex

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

答案 1 :(得分:2)

您可以将groupbyapply(pd.Series)

一起使用
df.groupby(['ID','col']).col2.apply(list).apply(pd.Series).add_prefix('col').reset_index()
Out[404]: 
   ID col  col0  col1
0   1   A  50.0  52.0
1   1   B  45.0   NaN
2   1   C  18.0   NaN

答案 2 :(得分:1)

不确定这是否是您要找的,但它会呈现您正在寻找的相同结果。请注意我在同一列上使用多个聚合函数,因此使用ravel函数来展平数据帧列。

import pandas as pd
import numpy as np

df = pd.DataFrame({'ID':[1,1,1,1], 
                  'Col1':['A','A','B','C'],
                 'Col2':[50,52,45,18]})

df = df.groupby(['ID','Col1']).agg({'Col2':['first','last']})
df.columns = ["_".join(x) for x in df.columns.ravel()]
df = df.reset_index()
df['Col2_last'] = np.where(df.Col2_first == df.Col2_last, float('nan'), df.Col2_last)

print(df)