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相同的行数。
答案 0 :(得分:2)
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)
您可以将groupby
与apply(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)