Tengo un marco de datos de pandas, dentro del marco de datos tengo dos series / columnas que deseo combinar en una nueva serie / columna. Ya tengo un bucle for que hace lo que necesito, pero prefiero que esté en una lista de comprensión, pero no puedo entenderlo. Además, mi código tarda mucho tiempo en ejecutarse. Leí que las comprensiones de listas se ejecutan más rápido, ¿tal vez hay una manera más rápida?

Si los valores de 'lead_owner' coinciden con los valores distintos / únicos de 'agent_final', use ese valor. De lo contrario, use los valores de 'agent_final'

for x, y in zip(list(df['lead_owner']), list(df['agent_final'])):
    if x in set(df['agent_final']):
        my_list .append(x)
    else:
        my_list .append(y)
1
Ryan Davies 30 sep. 2019 a las 15:38

4 respuestas

La mejor respuesta

La forma de hacerlo usando la comprensión de la lista:

my_list = [x if x in set(df['agent_final']) else y for (x,y) in zip(list(df['lead_owner']), list(df['agent_final']))]

Es bastante difícil decir por qué su código se ejecuta lentamente, a menos que sepa cuál es el tamaño de sus datos.

Una forma de acelerar su código con seguridad es no construir el conjunto cada vez que verifique si x está en el conjunto. Construya el conjunto fuera de la comprensión del bucle / lista:

agent_final_set = set(df['agent_final'])
my_list = [x if x in agent_final_set else y for (x,y) in zip(list(df['lead_owner']), list(df['agent_final']))]
2
Nico Griffioen 30 sep. 2019 a las 12:53

Con numpy.where one-liner:

my_list = np.where(df.lead_owner.isin(df.agent_final), df.lead_owner, df.agent_final)

Ejemplo simple:

In [284]: df
Out[284]: 
  lead_owner agent_final
0          a           1
1          b           2
2          c           a
3          e           c

In [285]: np.where(df.lead_owner.isin(df.agent_final), df.lead_owner, df.agent_final)
Out[285]: array(['a', '2', 'c', 'c'], dtype=object)
0
RomanPerekhrest 30 sep. 2019 a las 12:51

Te sugiero que pruebes los pandas apply y compartas el rendimiento:

agents = set(df['agent_final'])
df['result'] = df.apply(lambda x: x['lead_owner'] if x['lead_owner'] in agents else x['agent_final'], axis=1)

Y hacer un to_list si es necesario

1
Ketan 30 sep. 2019 a las 12:58

Eliminé un código innecesario y extraje la creación del conjunto fuera del bucle principal. Veamos si esto funciona más rápido:

agents = set(df['agent_final'])
data = zip(df['lead_owner'], df['agent_final'])
result = [x if x in agents else y for x, y in data]
1
Óscar López 30 sep. 2019 a las 12:49
58168084