Chciałbym uzupełnić brakujące wartości w jednej kolumnie wartościami z innej kolumny, używając fillna
metody.
(Czytałem, że zapętlanie każdego wiersza byłoby bardzo złą praktyką i że lepiej byłoby zrobić wszystko za jednym razem, ale nie mogłem się dowiedzieć, jak to zrobić fillna
.)
Dane przed:
Day Cat1 Cat2
1 cat mouse
2 dog elephant
3 cat giraf
4 NaN ant
Dane po:
Day Cat1 Cat2
1 cat mouse
2 dog elephant
3 cat giraf
4 ant ant
fillna
trwa seria.Mógłbyś
Ogólna konstrukcja na RHS wykorzystuje trójskładnikowy wzorzec z
pandas
książki kucharskiej (którą warto przeczytać w każdym przypadku). To wersja wektorowaa? b: c
.źródło
pd.DataFrame.fillna()
. I podejrzewam, że zachowanie w narożniku może się różnić, np. Dla niedopasowanych długości serii z różnych ramek danych: dfA ['Cat1'], dfB ['Cat2']Po prostu użyj
value
parametru zamiastmethod
:In [20]: df Out[20]: Cat1 Cat2 Day 0 cat mouse 1 1 dog elephant 2 2 cat giraf 3 3 NaN ant 4 In [21]: df.Cat1 = df.Cat1.fillna(value=df.Cat2) In [22]: df Out[22]: Cat1 Cat2 Day 0 cat mouse 1 1 dog elephant 2 2 cat giraf 3 3 ant ant 4
źródło
value
to pierwszy parametr, więc joris robi dokładnie to samo. Jak powiedział, zobacz dokumentację .method
jest tam wymieniony jako pierwszy.pandas.DataFrame.combine_first również działa.
( Uwaga: ponieważ „kolumny indeksu wyników będą sumą odpowiednich indeksów i kolumn”, należy sprawdzić, czy indeks i kolumny są dopasowane ).
import numpy as np import pandas as pd df = pd.DataFrame([["1","cat","mouse"], ["2","dog","elephant"], ["3","cat","giraf"], ["4",np.nan,"ant"]],columns=["Day","Cat1","Cat2"]) In: df["Cat1"].combine_first(df["Cat2"]) Out: 0 cat 1 dog 2 cat 3 ant Name: Cat1, dtype: object
Porównaj z innymi odpowiedziami:
%timeit df["Cat1"].combine_first(df["Cat2"]) 181 µs ± 11.3 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each) %timeit df['Cat1'].fillna(df['Cat2']) 253 µs ± 10.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) %timeit np.where(df.Cat1.isnull(), df.Cat2, df.Cat1) 88.1 µs ± 793 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Nie użyłem tej metody poniżej:
def is_missing(Cat1,Cat2): if np.isnan(Cat1): return Cat2 else: return Cat1 df['Cat1'] = df.apply(lambda x: is_missing(x['Cat1'],x['Cat2']),axis=1)
ponieważ spowoduje to wyjątek:
TypeError: ("ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''", 'occurred at index 0')
co oznacza, że np.isnan można zastosować do tablic NumPy o rodzimym typie dtype (np.float64), ale wywołuje TypeError po zastosowaniu do tablic obiektów .
Więc poprawiam metodę:
def is_missing(Cat1,Cat2): if pd.isnull(Cat1): return Cat2 else: return Cat1 %timeit df.apply(lambda x: is_missing(x['Cat1'],x['Cat2']),axis=1) 701 µs ± 7.38 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
źródło
Oto bardziej ogólne podejście (prawdopodobnie lepsza jest metoda fillna)
def is_missing(Cat1,Cat2): if np.isnan(Cat1): return Cat2 else: return Cat1 df['Cat1'] = df.apply(lambda x: is_missing(x['Cat1'],x['Cat2']),axis=1)
źródło
Wiem, że to stare pytanie, ale ostatnio miałem potrzebę zrobienia czegoś podobnego. Udało mi się skorzystać z:
df = pd.DataFrame([["1","cat","mouse"], ["2","dog","elephant"], ["3","cat","giraf"], ["4",np.nan,"ant"]],columns=["Day","Cat1","Cat2"]) print(df) Day Cat1 Cat2 0 1 cat mouse 1 2 dog elephant 2 3 cat giraf 3 4 NaN ant df1 = df.bfill(axis=1).iloc[:, 1] df1 = df1.to_frame() print(df1)
Co daje:
Cat1 0 cat 1 dog 2 cat 3 ant
Mam nadzieję, że to komuś pomoże!
źródło