Fillna dans plusieurs colonnes en place dans les Pandas de Python
j'ai une base de données pandas de types mixtes, certains sont des chaînes et certains sont des nombres. Je voudrais remplacer les valeurs NAN dans les colonnes string par '.', et les valeurs de NAN dans les colonnes flottantes par 0.
considérez ce petit exemple fictif:
df = pd.DataFrame({'Name':['Jack','Sue',pd.np.nan,'Bob','Alice','John'],
'A': [1, 2.1, pd.np.nan, 4.7, 5.6, 6.8],
'B': [.25, pd.np.nan, pd.np.nan, 4, 12.2, 14.4],
'City':['Seattle','SF','LA','OC',pd.np.nan,pd.np.nan]})
Maintenant, je peux le faire en 3 lignes:
df['Name'].fillna('.',inplace=True)
df['City'].fillna('.',inplace=True)
df.fillna(0,inplace=True)
Puisqu'il s'agit d'une petite base de données, 3 lignes est probablement ok. Dans mon exemple réel (que je ne peux pas partager ici pour des raisons de confidentialité des données), j'ai beaucoup plus colonnes de chaîne et colonnes numériques. Alors j'ai fini par écrire beaucoup de lignes juste pour fillna. Y a-t-il une façon concise de le faire?
4 réponses
Vous pouvez utiliser apply
pour vos colonnes avec la vérification dtype
si numeric
ou non en cochant dtype.kind
:
res = df.apply(lambda x: x.fillna(0) if x.dtype.kind in 'biufc' else x.fillna('.'))
print(res)
A B City Name
0 1.0 0.25 Seattle Jack
1 2.1 0.00 SF Sue
2 0.0 0.00 LA .
3 4.7 4.00 OC Bob
4 5.6 12.20 . Alice
5 6.8 14.40 . John
vous pouvez soit lister les colonnes string à la main ou les glaner à partir de df.dtypes
. Une fois que vous avez la liste des colonnes string/object, vous pouvez appeler
# str_cols = ['Name','City']
str_cols = df.columns[df.dtypes==object]
df[str_cols] = df[str_cols].fillna('.')
df.fillna(0,inplace=True)
trouvé cette page en cherchant une réponse à ce problème, mais n'aimait pas les réponses existantes. J'ai fini par trouver quelque chose de mieux dans le DataFrame.documentation de fillna, et je me suis dit que je contribuerais pour n'importe qui d'autre qui se produirait sur ceci.
Si vous avez plusieurs colonnes, mais qui ne veulent remplacer le NaN
dans un sous-ensemble d'entre eux, vous pouvez utiliser:
df.fillna({'Name':'.', 'City':'.'}, inplace=True)
cela vous permet également de spécifier des remplacements différents pour chaque colonne. Et si vous voulez aller de l'avant et de remplir toutes les autres NaN
valeurs, vous pouvez simplement jeter un autre fillna
sur la fin:
df.fillna({'Name':'.', 'City':'.'}, inplace=True).fillna(0, inplace=True)
définir une fonction:
def myfillna(series):
if series.dtype is pd.np.dtype(float):
return series.fillna(0)
elif series.dtype is pd.np.dtype(object):
return series.fillna('.')
else:
return series
vous pouvez ajouter d'autres elif déclarations, si vous voulez remplir une colonne d'une autre dtype d'une autre façon. Maintenant appliquez cette fonction sur toutes les colonnes du dataframe
df = df.apply(myfillna)
c'est la même chose que 'place'