Lorsque vous avez un Pandas DataFrame comme celui-ci:
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
Mais avec environ 100 000 entrées, je cherche à trouver les ajouts et les suppressions de ces listes dans les deux colonnes par ligne.
Elle est comparable à cette question: Pandas: comment comparer les colonnes de listes en ligne dans un DataFrame avec Pandas (pas pour la boucle)? mais je regarde les différences, et la Pandas.apply
méthode ne semble pas être aussi rapide pour autant d'entrées. C'est le code que j'utilise actuellement. Pandas.apply
avec numpy's setdiff1d
méthode:
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)
Cela fonctionne bien, mais cela prend environ une minute pour 120 000 entrées. Existe-t-il un moyen plus rapide d'accomplir cela?
Réponses:
Je ne suis pas sûr des performances, mais en l'absence d'une meilleure solution, cela pourrait s'appliquer:
Déménagements:
Ajouts:
la source
applymap
, mais heureux que cela ait fonctionné pour vous!la source
Je vais vous suggérer de calculer
additions
etremovals
dans le même cas d'appliquer.Générez un plus grand exemple
Votre solution
Votre solution sur une seule demande
En utilisant
set
À moins que vos listes soient très grandes, vous pouvez éviter
numpy
La solution de @ r.ook
Si vous êtes satisfait d'avoir des ensembles au lieu de listes en sortie, vous pouvez utiliser le code de @ r.ook
La solution de @Andreas K.
et vous pouvez éventuellement ajouter
.apply(list)
pour obtenir votre même sortiela source
En voici une avec l'idée de décharger la partie de calcul vers des outils NumPy vectorisés. Nous rassemblerons toutes les données dans des tableaux uniques pour chaque en-tête, effectuerons toutes les correspondances requises sur NumPy et, enfin, nous redirigerons vers les entrées de ligne requises. Sur le NumPy qui effectue la partie de levage de charges lourdes, nous utiliserons le hachage en fonction des ID de groupe et des ID au sein de chaque groupe utilisant
np.searchsorted
. Nous utilisons également des nombres car ceux-ci sont plus rapides avec NumPy. L'implémentation ressemblerait à ceci -Une optimisation supplémentaire est possible aux étapes de calcul
t_mask
ety_mask
,np.searchsorted
pourrait être réutilisée.Nous pourrions également utiliser une simple affectation de tableau comme alternative à l'
isin
étape pour obtenirt_mask
ety_mask
, comme ça -la source