Jeśli masz ramkę danych Pandas taką jak ta:
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
Ale mając około 100 000 wpisów, szukam dodawania i usuwania tych list w dwóch kolumnach według wierszy.
Jest to porównywalne z tym pytaniem: Pandas: Jak porównać kolumny z wierszami w ramce danych z Pandami (nie dla pętli)? ale patrzę na różnice, a Pandas.apply
metoda wydaje się nie być tak szybka dla tak wielu wpisów. To jest kod, którego obecnie używam. Pandas.apply
z numpy's setdiff1d
metodą:
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)
Działa to dobrze, jednak 120 000 wpisów zajmuje około minuty. Czy jest więc szybszy sposób na osiągnięcie tego?
Odpowiedzi:
Nie jestem pewien co do wydajności, ale przy braku lepszego rozwiązania może to mieć zastosowanie:
Przeprowadzki:
Wzbogacenie:
źródło
applymap
, ale cieszę się, że Ci się udało!źródło
Zasugeruję, abyś obliczył
additions
iremovals
w ramach tego samego zastosowania.Wygeneruj większy przykład
Twoje rozwiązanie
Twoje rozwiązanie dotyczy tylko jednego
Za pomocą
set
Chyba że twoje listy są bardzo duże, których możesz uniknąć
numpy
Rozwiązanie @ r.ook
Jeśli jesteś zadowolony z posiadania zestawów zamiast list jako danych wyjściowych, możesz użyć kodu @ r.ook
@Andreas K. rozwiązanie
i możesz w końcu dodać,
.apply(list)
aby uzyskać ten sam wynikźródło
Oto pomysł przeniesienia części obliczeniowej na wektoryzowane narzędzia NumPy. Zbierzemy wszystkie dane do pojedynczych tablic dla każdego nagłówka, wykonamy wszystkie wymagane dopasowanie na NumPy i ostatecznie przekroimy z powrotem do wymaganych pozycji wierszy. Na NumPy, który wykonuje część do podnoszenia ciężarów, będziemy używać haszowania na podstawie identyfikatorów grup i identyfikatorów w obrębie każdej używanej grupy
np.searchsorted
. Korzystamy również z liczb, ponieważ są one szybsze dzięki NumPy. Implementacja wyglądałaby mniej więcej tak -Dalsza optymalizacja jest możliwa na etapach obliczania
t_mask
iy_mask
, gdzienp.searchsorted
można go ponownie użyć.Moglibyśmy również użyć prostego przypisania tablicy jako alternatywy dla
isin
kroku, który należy wykonać,t_mask
ay_mask
tak -źródło