Je voudrais remplir les valeurs manquantes dans une colonne avec des valeurs d'une autre colonne, en utilisant la fillna
méthode.
(J'ai lu que parcourir chaque ligne en boucle serait une très mauvaise pratique et qu'il serait préférable de tout faire en une seule fois, mais je ne pouvais pas savoir comment le faire fillna
.)
Données avant:
Day Cat1 Cat2
1 cat mouse
2 dog elephant
3 cat giraf
4 NaN ant
Données après:
Day Cat1 Cat2
1 cat mouse
2 dog elephant
3 cat giraf
4 ant ant
fillna
prend une série.Vous pourriez faire
La construction globale sur le RHS utilise le modèle ternaire du
pandas
livre de cuisine (qu'il vaut la peine de lire dans tous les cas). C'est une version vectorielle dea? b: c
.la source
pd.DataFrame.fillna()
. Et je soupçonne que le comportement de la casse d'angle peut différer, par exemple pour les longueurs de série non concordantes de différentes dataframes: dfA ['Cat1'], dfB ['Cat2']Utilisez simplement le
value
paramètre au lieu 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
la source
value
est le premier paramètre, donc joris fait exactement la même chose. Comme il l'a dit, consultez la documentation .method
indiqué en premier.pandas.DataFrame.combine_first fonctionne également.
( Attention: puisque "Les colonnes d'index de résultat seront l'union des index et des colonnes respectifs", vous devez vérifier que l'index et les colonnes correspondent. )
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
Comparez avec d'autres réponses:
%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)
Je n'ai pas utilisé cette méthode ci-dessous:
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)
car cela lèvera une exception:
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')
ce qui signifie que np.isnan peut être appliqué aux tableaux NumPy de type dtype natif (comme np.float64), mais lève TypeError lorsqu'il est appliqué aux tableaux d' objets .
Je révise donc la méthode:
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)
la source
Voici une approche plus générale (la méthode fillna est probablement meilleure)
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)
la source
Je sais que c'est une vieille question, mais j'avais besoin de faire quelque chose de similaire récemment. J'ai pu utiliser les éléments suivants:
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)
Ce qui donne:
Cat1 0 cat 1 dog 2 cat 3 ant
J'espère que cela est utile à quelqu'un!
la source