Avant de continuer avec ce post, il est important de comprendre la différence entre NaN et None . L'un est un type flottant, l'autre un type objet. Pandas est mieux adapté pour travailler avec des types scalaires car de nombreuses méthodes de ces types peuvent être vectorisées. Pandas essaie de gérer None et NaN de manière cohérente, mais NumPy ne le peut pas.
Ma suggestion ( et celle d'Andy ) est de s'en tenir à NaN.
Mais pour répondre à votre question...
pandas >= 0.18 : Utilisation de na_values=['-']
argument avec read_csv
Si vous avez chargé ces données à partir de CSV/Excel, j'ai de bonnes nouvelles pour vous. Vous pouvez éliminer ce problème à la racine, pendant le chargement des données, au lieu de devoir écrire un correctif avec du code dans une étape ultérieure.
La plupart des pd.read_*
fonctions (telles que read_csv
y read_excel
) accepter un na_values
attribut.
file.csv
A,B
-,1
3,-
2,-
5,3
1,-2
-5,4
-1,-1
-,0
9,0
Maintenant, pour convertir le -
en NaNs, faire,
import pandas as pd
df = pd.read_csv('file.csv', na_values=['-'])
df
A B
0 NaN 1.0
1 3.0 NaN
2 2.0 NaN
3 5.0 3.0
4 1.0 -2.0
5 -5.0 4.0
6 -1.0 -1.0
7 NaN 0.0
8 9.0 0.0
Et similaire pour d'autres fonctions/formats de fichiers.
P.S. : Sur la v0.24+, vous pouvez préserver le type entier même si votre colonne contient des NaNs (oui, c'est comme avoir le gâteau et le manger aussi). Vous pouvez spécifier dtype='Int32'
df = pd.read_csv('file.csv', na_values=['-'], dtype='Int32')
df
A B
0 NaN 1
1 3 NaN
2 2 NaN
3 5 3
4 1 -2
5 -5 4
6 -1 -1
7 NaN 0
8 9 0
df.dtypes
A Int32
B Int32
dtype: object
Le dtype n'est pas un type int conventionnel... mais plutôt un type Nullable Integer Type. Il existe d'autres options.
Manipulation de données numériques : pd.to_numeric
con errors='coerce
Si vous traitez des données numériques, une solution plus rapide est d'utiliser pd.to_numeric
avec le errors='coerce'
qui convertit les valeurs invalides (valeurs qui ne peuvent pas être converties en numérique) en NaN.
pd.to_numeric(df['A'], errors='coerce')
0 NaN
1 3.0
2 2.0
3 5.0
4 1.0
5 -5.0
6 -1.0
7 NaN
8 9.0
Name: A, dtype: float64
Pour conserver le dtype integer (nullable), utilisez
pd.to_numeric(df['A'], errors='coerce').astype('Int32')
0 NaN
1 3
2 2
3 5
4 1
5 -5
6 -1
7 NaN
8 9
Name: A, dtype: Int32
Pour contraindre plusieurs colonnes, utilisez apply
:
df[['A', 'B']].apply(pd.to_numeric, errors='coerce').astype('Int32')
A B
0 NaN 1
1 3 NaN
2 2 NaN
3 5 3
4 1 -2
5 -5 4
6 -1 -1
7 NaN 0
8 9 0
...et de réaffecter le résultat après.
Vous trouverez de plus amples informations dans cette réponse .