Me gustaría completar los valores faltantes en una columna con valores de otra columna, usando el fillna
método.
(Leí que recorrer cada fila sería una muy mala práctica y que sería mejor hacer todo de una vez, pero no pude averiguar cómo hacerlo fillna
).
Datos antes:
Day Cat1 Cat2
1 cat mouse
2 dog elephant
3 cat giraf
4 NaN ant
Datos después:
Day Cat1 Cat2
1 cat mouse
2 dog elephant
3 cat giraf
4 ant ant
fillna
lleva una serie.Podrías hacerlo
La construcción general en el RHS utiliza el patrón ternario del
pandas
libro de cocina (que vale la pena leer en cualquier caso). Es una versión vectorial dea? b: c
.fuente
pd.DataFrame.fillna()
. Y sospecho que el comportamiento del caso de esquina puede diferir, por ejemplo, para longitudes de series no coincidentes de diferentes marcos de datos: dfA ['Cat1'], dfB ['Cat2']Simplemente use el
value
parámetro en lugar 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
fuente
value
es el primer parámetro, por lo que joris está haciendo exactamente lo mismo. Como dijo, consulte los documentos .method
se enumera allí primero.pandas.DataFrame.combine_first también funciona.
( Atención: dado que "Las columnas de índice de resultados serán la unión de los índices y columnas respectivos", debe verificar que el índice y las columnas coincidan ) .
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 con otras respuestas:
%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)
No utilicé este método a continuación:
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 generará una excepción:
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')
lo que significa que np.isnan se puede aplicar a matrices NumPy de dtype nativo (como np.float64), pero genera TypeError cuando se aplica a matrices de objetos .
Entonces reviso el 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)
fuente
Aquí hay un enfoque más general (el método fillna es probablemente mejor)
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)
fuente
Sé que esta es una pregunta antigua, pero recientemente tuve la necesidad de hacer algo similar. Pude usar lo siguiente:
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)
Cuyos rendimientos:
Cat1 0 cat 1 dog 2 cat 3 ant
¡Espero que esto sea útil para alguien!
fuente