Mam DataFrame z wieloma brakującymi wartościami w kolumnach, które chcę pogrupować według:
import pandas as pd
import numpy as np
df = pd.DataFrame({'a': ['1', '2', '3'], 'b': ['4', np.NaN, '6']})
In [4]: df.groupby('b').groups
Out[4]: {'4': [0], '6': [2]}
zobacz, że Pandy porzuciły wiersze z wartościami docelowymi NaN. (Chcę uwzględnić te wiersze!)
Ponieważ potrzebuję wielu takich operacji (wiele kolumn ma brakujące wartości) i używam bardziej skomplikowanych funkcji niż tylko mediany (zazwyczaj losowe lasy), chcę uniknąć pisania zbyt skomplikowanych fragmentów kodu.
Jakieś sugestie? Powinienem napisać funkcję do tego, czy istnieje proste rozwiązanie?
dropna=False
w,groupby()
aby uzyskać pożądany rezultat. Więcej informacjiOdpowiedzi:
Wspomniano o tym w sekcji Brakujące dane w dokumentach :
Jednym obejściem jest użycie symbolu zastępczego przed wykonaniem grupowania (np. -1):
To powiedziawszy, wydaje się dość okropny hack ... być może powinna istnieć opcja włączenia NaN w groupby (zobacz ten problem na github - który używa tego samego hackowania).
źródło
Starożytny temat, jeśli ktoś wciąż się o to potyka - innym obejściem jest przekonwertowanie przez .astype (str) na string przed grupowaniem. To ochroni NaN.
źródło
sum
Oa
to ciąg konkatenacji tutaj, a nie suma numeryczny. To tylko „działa”, ponieważ „b” składa się z odrębnych wpisów. Potrzebujesz „a” jako liczby, a „b” jako ciągu znakówpandy> = 1.1
Od pandy 1.1 masz lepszą kontrolę nad tym zachowaniem, wartości NA są teraz dozwolone w grupie przy użyciu
dropna=False
:źródło
Nie mogę dodać komentarza do M. Kiewischa, ponieważ nie mam wystarczającej liczby punktów reputacji (mam tylko 41, ale potrzebuję więcej niż 50, aby skomentować).
W każdym razie chcę tylko zaznaczyć, że rozwiązanie M. Kiewischa nie działa tak, jak jest i może wymagać dalszych poprawek. Rozważmy na przykład
co pokazuje, że dla grupy b = 4,0, odpowiadająca jej wartość to 15 zamiast 6. Tutaj jest to po prostu konkatenacja 1 i 5 jako łańcuchy zamiast dodawania ich jako liczb.
źródło
b
kolumnęJedna mała uwaga na temat rozwiązania Andy'ego Haydena - nie działa (już?), Ponieważ
np.nan == np.nan
dajeFalse
, więcreplace
funkcja tak naprawdę nic nie robi.U mnie zadziałało:
(Przynajmniej takie jest zachowanie w przypadku Pand w wersji 0.19.2. Przepraszam, że dodam to jako inną odpowiedź, nie mam wystarczającej reputacji, aby komentować).
źródło
df['b'].fillna(-1)
.Wszystkie odpowiedzi udzielone do tej pory skutkują potencjalnie niebezpiecznym zachowaniem, ponieważ jest całkiem możliwe, że wybierzesz wartość fikcyjną, która jest w rzeczywistości częścią zbioru danych. Jest to coraz bardziej prawdopodobne, gdy tworzysz grupy o wielu atrybutach. Mówiąc najprościej, podejście to nie zawsze dobrze uogólnia.
Mniej hakerskim rozwiązaniem jest użycie pd.drop_duplicates () do stworzenia unikalnego indeksu kombinacji wartości, z których każda ma własny identyfikator, a następnie grupowanie według tego identyfikatora. Jest bardziej szczegółowy, ale spełnia swoje zadanie:
Pamiętaj, że możesz teraz po prostu wykonać następujące czynności:
Spowoduje to zwrócenie pomyślnego wyniku bez martwienia się o nadpisanie rzeczywistych danych, które są mylone jako wartość fikcyjna.
źródło
Odpowiedziałem już na to, ale z jakiegoś powodu odpowiedź została zamieniona na komentarz. Niemniej jest to najbardziej wydajne rozwiązanie:
Brak możliwości włączenia (i propagowania) NaN w grupach jest dość denerwujący. Cytowanie R nie jest przekonujące, ponieważ takie zachowanie nie jest spójne z wieloma innymi rzeczami. W każdym razie, sztuczny hack jest również dość zły. Jednak rozmiar (obejmuje NaN) i liczba (ignoruje NaN) grupy będą się różnić, jeśli istnieją NaN.
Jeśli te wartości się różnią, można ustawić wartość z powrotem na Brak dla wyniku funkcji agregującej dla tej grupy.
źródło
Zainstalowałem Pandy 1.1 w Anaconda
Nie jestem w stanie skomentować odpowiedzi cs95, ale pomógł mi rozwiązać problem.
Próbowałem zainstalować Pandas 1.1, ale nie udało mi się użyć jego kodu, więc przeszukałem go i mogłem zainstalować.
Najpierw uruchamiam monit anaconda jako administrator i wklejam następujący kod:
pip install pandas==1.1.0rc0
Następnie należy użyć
dropna = False
Link: https://libraries.io/pypi/pandas
źródło
df = df.fillna("")
to działało dla mnieźródło