Tengo un marco de datos de pandas existente a continuación:
id time cd 0 1 1 2 3 1 1 3 1 6 2 2 2 3 2 3 2 3 8 6También tengo valores almacenados en una lista como:
list = [0.4, 0.6]Quiero crear una nueva columna en el marco de fecha existente y asignar cada elemento de la lista en la primera fila para cada grupo (id) como:
id time cd new_col 0 1 1 2 3 0.4 1 1 3 1 6 2 2 2 3 2 0.6 3 2 3 8 6Agrupe el marco de datos por id y use cumcount para crear un contador secuencial, luego use la indexación booleana con loc para asignar los valores de la lista donde el valor del contador es 0
lst = [0.4, 0.6] df.loc[df.groupby('id').cumcount().eq(0), 'new_col'] = lst id time cd new_col 0 1 1 2 3 0.4 1 1 3 1 6 NaN 2 2 2 3 2 0.6 3 2 3 8 6 NaNUse Series.map con el diccionario creado por enumerate y establezca valores solo primero por grupos en Series.mask con Series.duplicated :
L=[0.4, 0.6] df["new_col"] = df['id'].sub(1).map(dict(enumerate(L))).mask(df['id'].duplicated()) print (df) id time cd new_col 0 1 1 2 3 0.4 1 1 3 1 6 NaN 2 2 2 3 2 0.6 3 2 3 8 6 NaN L=[0.4, 0.6] df["new_col"] = df['id'].sub(1).map(dict(enumerate(L))).mask(df['id'].duplicated(),'') print (df) id time cd new_col 0 1 1 2 3 0.4 1 1 3 1 6 2 2 2 3 2 0.6 3 2 3 8 6 Si es posible, cualquier grupo en id , por ejemplo 10, 20 use GroupBy.ngroup :
L=[0.4, 0.6] df["new_col"] = (df.groupby('id').ngroup().map(dict(enumerate(L))) .mask(df['id'].duplicated(),'')) print (df) id time cd new_col 0 10 1 2 3 0.4 1 10 3 1 6 2 20 2 3 2 0.6 3 20 3 8 6¿Esto ayuda a resolver su problema? (No veo ningún beneficio en solo poner ese valor en la primera aparición del grupo y no en los otros valores)
mapping = {1: 0.4, 2: 0.6} df["new_col"] = df['id'].map(mapping)Resultado:
Nota: si todos sus ID son números enteros secuenciales que comienzan en 1 y todos los valores en su lista también están en ese orden correcto, puede convertirlo en un dictado de mapeo usando:
mapping = {i+1: value for i, value in enumerate(your_list)}