Busco hacer tarea similar como en este hilo: Combinar varios valores de columna en una columna de pandas pitón
Pero la diferencia es que me gustaría crear una nueva columna que combina todos los valores no nulos en una columna después de la agrupación por otra columna (s). Aquí es un ejemplo de juguete:
df= pd.DataFrame({'ID1' : [1,1,2,2,3,3,3],'ID2' : ['a','a','b','b','c','c','c'],
'Status' : pd.Series([np.nan,'1', np.nan,'1','2',np.nan,'1'],
dtype="category")})
df
Out[74]:
ID1 ID2 Status
0 1 a NaN
1 1 a 1
2 2 b NaN
3 2 b 1
4 3 c 2
5 3 c NaN
6 3 c 1
Entonces quiero groupby
ID1
y ID2
:
gr = df.groupby(['ID1','ID2'])
Entonces, me gustaría que mi mirada resultado como este:
Out:
NewCol
0 1
1 1
2 2,1
Por lo que es una nueva DataFrame
que contiene los non-null
valores de Status
la columna agrupadas por ID1
y ID2
.
Gracias por adelantado.
Uso GroupBy.agg
con función lambda es la solución más general:
df1 = df.groupby(['ID1','ID2'])['Status'].agg(lambda x: ','.join(x.dropna())).reset_index()
print (df1)
ID1 ID2 Status
0 1 a 1
1 2 b 1
2 3 c 2,1
Otra idea es quitar duplicado en el primer paso, pero si algún grupo con valores solo misisng se elimina de la salida, por lo que es necesario el procesamiento siguiente como merge
:
#first group with only NaNs
df= pd.DataFrame({'ID1' : [1,1,2,2,3,3,3],'ID2' : ['a','a','b','b','c','c','c'],
'Status' : pd.Series([np.nan,np.nan, np.nan,'1','2',np.nan,'1'],
dtype="category")})
#first group is dropped
df11 = (df.dropna(subset=['Status'])
.groupby(['ID1','ID2'])['Status']
.agg(','.join)
.reset_index())
print (df11)
ID1 ID2 Status
0 2 b 1
1 3 c 2,1
#added missing pairs and `NaN`s converted to empty strings:
df2 = df.drop_duplicates(['ID1','ID2'])[['ID1','ID2']].merge(df11, how='left').fillna('')
print (df2)
ID1 ID2 Status
0 1 a
1 2 b 1
2 3 c 2,1
Primera solución:
df1 = df.groupby(['ID1','ID2'])['Status'].agg(lambda x: ','.join(x.dropna())).reset_index()
print (df1)
ID1 ID2 Status
0 1 a
1 2 b 1
2 3 c 2,1