Al tener un Pandas DataFrame como este:
import pandas as pd
import numpy as np
df = pd.DataFrame({'today': [['a', 'b', 'c'], ['a', 'b'], ['b']],
'yesterday': [['a', 'b'], ['a'], ['a']]})
today yesterday
0 ['a', 'b', 'c'] ['a', 'b']
1 ['a', 'b'] ['a']
2 ['b'] ['a']
... etc
Pero con alrededor de 100 000 entradas, estoy buscando encontrar las adiciones y eliminaciones de esas listas en las dos columnas en forma de fila.
Es comparable a esta pregunta: Pandas: ¿Cómo comparar columnas de listas en fila en un DataFrame con Pandas (no para bucle)? pero estoy mirando las diferencias, y el Pandas.apply
método no parece ser tan rápido para tantas entradas. Este es el código que estoy usando actualmente. Pandas.apply
con numpy's setdiff1d
método:
additions = df.apply(lambda row: np.setdiff1d(row.today, row.yesterday), axis=1)
removals = df.apply(lambda row: np.setdiff1d(row.yesterday, row.today), axis=1)
Esto funciona bien, sin embargo, toma alrededor de un minuto para 120 000 entradas. Entonces, ¿hay una manera más rápida de lograr esto?
Respuestas:
No estoy seguro sobre el rendimiento, pero a falta de una mejor solución, esto podría aplicarse:
Mudanzas:
Adiciones:
fuente
applymap
, pero me alegro de que te haya funcionado.fuente
Le sugeriré que calcule
additions
yremovals
dentro de la misma solicitud.Genera un ejemplo más grande
Tu solución
Su solución en una sola solicitud
Utilizando
set
A menos que sus listas sean muy grandes, puede evitar
numpy
La solución de @ r.ook
Si está contento de tener conjuntos en lugar de listas como salida, puede usar el código de @ r.ook
La solución de @Andreas K.
y eventualmente puedes agregar
.apply(list)
para obtener tu mismo resultadofuente
Aquí hay uno con la idea de descargar la parte de cálculo a las herramientas vectorizadas de NumPy. Recopilaremos todos los datos en matrices individuales para cada encabezado, realizaremos todas las coincidencias requeridas en NumPy y finalmente volveremos a las entradas de fila requeridas. En el NumPy que realiza la parte de levantamiento pesado, usaremos hashing en función de las ID de grupo y las ID dentro de cada grupo que use
np.searchsorted
. También estamos haciendo uso de números, ya que son más rápidos con NumPy. La implementación se vería así:Es posible una mayor optimización en los pasos para calcular
t_mask
yy_mask
dóndenp.searchsorted
podría usarse nuevamente.También podríamos usar una simple asignación de matriz como una alternativa al
isin
paso para obtenert_mask
yy_mask
, así:fuente