Étant donné que nous recherchons le moyen le plus efficace
, c'est-à-dire les performances, utilisons des données de tableau pour tirer parti de NumPy. Nous découperons des tranches uniques et comparerons, comme la méthode de décalage discutée précédemment dans le post de @EdChum
. Mais avec NumPy slicing, nous nous retrouverions avec un tableau en moins, nous devons donc concaténer avec un élément Vrai
au début pour sélectionner le premier élément et, par conséquent, nous aurions une implémentation comme suit -
def drop_consecutive_duplicates(a):
ar = a.values
retourne a[np.concatenate(([True],ar[:-1]!= ar[1:]))]
Exécution d'exemple -
Entrée [149]: a
Sortie [149]:
1 1
2 2
3 2
4 3
5 2
dtype: int64
En [150]: drop_consecutive_duplicates(a)
Sortie [150]:
1 1
2 2
4 3
5 2
dtype: int64
Chronométrage sur de grands tableaux comparant la solution de @EdChum
-
Entrée [142]: a = pd.Series(np.random.randint(1,5,(1000000)))
En [143]: %timeit a.loc[a.shift() != a]
100 boucles, meilleure de 3: 12,1 ms par boucle
En [144]: %timeit drop_consecutive_duplicates(a)
100 boucles, meilleure de 3: 11 ms par boucle
En [145]: a = pd.Series(np.random.randint(1,5,(10000000)))
En [146]: %timeit a.loc[a.shift() != a]
10 boucles, meilleure de 3: 136 ms par boucle
En [147]: %timeit drop_consecutive_duplicates(a)
10 boucles, meilleure de 3: 114 ms par boucle
Donc, il y a une amélioration!
Obtenez un important boost pour les valeurs uniquement!
Si seules les valeurs sont nécessaires, nous pourrions obtenir un important boost en indexant simplement les données du tableau, comme ceci -
def drop_consecutive_duplicates(a):
ar = a.values
retourne ar[np.concatenate(([True],ar[:-1]!= ar[1:]))]
Exécution d'exemple -
Entrée [170]: a = pandas.Series([1,2,2,3,2], index=[1,2,3,4,5])
En [171]: drop_consecutive_duplicates(a)
Sortie [171]: tableau([1, 2, 3, 2])
Chronométrage -
Entrée [173]: a = pd.Series(np.random.randint(1,5,(10000000)))
En [174]: %timeit a.loc[a.shift() != a]
10 boucles, meilleure de 3: 137 ms par boucle
En [175]: %timeit drop_consecutive_duplicates(a)
10 boucles, meilleure de 3: 61,3 ms par boucle