Gostaria de preencher os valores ausentes em uma coluna com valores de outra coluna, usando o fillna
método.
(Li que repetir cada linha seria uma prática muito ruim e que seria melhor fazer tudo de uma vez, mas não consegui descobrir como fazer isso fillna
.)
Dados anteriores:
Day Cat1 Cat2
1 cat mouse
2 dog elephant
3 cat giraf
4 NaN ant
Dados depois de:
Day Cat1 Cat2
1 cat mouse
2 dog elephant
3 cat giraf
4 ant ant
fillna
leva uma série.Você poderia fazer
A construção geral do RHS usa o padrão ternário do
pandas
livro de receitas (que vale a pena ler em qualquer caso). É uma versão vetorial dea? b: c
.fonte
pd.DataFrame.fillna()
. E eu suspeito que o comportamento do caso extremo pode ser diferente, por exemplo, para comprimentos de série incompatíveis de diferentes dataframes: dfA ['Cat1'], dfB ['Cat2']Basta usar o
value
parâmetro em vez demethod
: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
fonte
value
é o primeiro parâmetro, então joris está realmente fazendo exatamente a mesma coisa. Como ele disse, veja os docs .method
está listada primeiro.pandas.DataFrame.combine_first também funciona.
( Atenção: como "As colunas do índice de resultado serão a união dos respectivos índices e colunas", você deve verificar se o índice e as colunas são correspondidos. )
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
Compare com outras respostas:
%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)
Não usei este método abaixo:
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)
porque levantará uma exceção:
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')
o que significa que np.isnan pode ser aplicado a arrays NumPy de dtype nativo (como np.float64), mas aumenta TypeError quando aplicado a arrays de objetos .
Então, eu reviso o método:
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)
fonte
Aqui está uma abordagem mais geral (o método fillna é provavelmente melhor)
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)
fonte
Sei que essa é uma pergunta antiga, mas recentemente precisei fazer algo semelhante. Consegui usar o seguinte:
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)
O que produz:
Cat1 0 cat 1 dog 2 cat 3 ant
Espero que isto ajude alguém!
fonte