238 votes

Remplacement des valeurs vides (espace blanc) par NaN dans pandas

Je veux trouver toutes les valeurs dans un cadre de données Pandas qui contiennent des espaces (n'importe quelle quantité arbitraire) et remplacer ces valeurs par des NaN.

Avez-vous des idées sur la façon d'améliorer cette situation ?

En gros, je veux tourner ça :

                   A    B    C
2000-01-01 -0.532681  foo    0
2000-01-02  1.490752  bar    1
2000-01-03 -1.387326  foo    2
2000-01-04  0.814772  baz     
2000-01-05 -0.222552         4
2000-01-06 -1.176781  qux     

Dans ça :

                   A     B     C
2000-01-01 -0.532681   foo     0
2000-01-02  1.490752   bar     1
2000-01-03 -1.387326   foo     2
2000-01-04  0.814772   baz   NaN
2000-01-05 -0.222552   NaN     4
2000-01-06 -1.176781   qux   NaN

J'ai réussi à le faire avec le code ci-dessous, mais c'est vraiment moche. Ce n'est pas Python et je suis sûr que ce n'est pas non plus l'utilisation la plus efficace de pandas. Je boucle à travers chaque colonne et je fais un remplacement booléen par rapport à un masque de colonne généré en appliquant une fonction qui fait une recherche regex de chaque valeur, avec correspondance sur les espaces.

for i in df.columns:
    df[i][df[i].apply(lambda i: True if re.search('^\s*$', str(i)) else False)]=None

On pourrait l'optimiser un peu en n'itérant que sur les champs qui peuvent contenir des chaînes vides :

if df[i].dtype == np.dtype('object')

Mais ce n'est pas une grande amélioration

Et enfin, ce code définit les chaînes cibles à None, ce qui fonctionne avec les fonctions de Pandas telles que fillna() mais ce serait bien, par souci d'exhaustivité, de pouvoir insérer un fichier NaN directement au lieu de None .

306voto

patricksurry Points 527

Je pense df.replace() fait l'affaire, puisque pandas 0.13 :

df = pd.DataFrame([
    [-0.532681, 'foo', 0],
    [1.490752, 'bar', 1],
    [-1.387326, 'foo', 2],
    [0.814772, 'baz', ' '],     
    [-0.222552, '   ', 4],
    [-1.176781,  'qux', '  '],         
], columns='A B C'.split(), index=pd.date_range('2000-01-01','2000-01-06'))

# replace field that's entirely space (or empty) with NaN
print(df.replace(r'^\s*$', np.nan, regex=True))

Produit :

                   A    B   C
2000-01-01 -0.532681  foo   0
2000-01-02  1.490752  bar   1
2000-01-03 -1.387326  foo   2
2000-01-04  0.814772  baz NaN
2000-01-05 -0.222552  NaN   4
2000-01-06 -1.176781  qux NaN

Comme Temak l'a signalé, utilisez df.replace(r'^\s+$', np.nan, regex=True) dans le cas où vos données valides contiennent des espaces blancs.

105voto

Philipp Schwarz Points 4503

Si vous souhaitez remplacer une chaîne de caractères vide et des enregistrements ne contenant que des espaces, la fonction La réponse correcte est ! :

df = df.replace(r'^\s*$', np.nan, regex=True)

La réponse acceptée

df.replace(r'\s+', np.nan, regex=True)

Ne remplace pas une chaîne vide !, vous pouvez essayer vous-même avec l'exemple donné légèrement mis à jour :

df = pd.DataFrame([
    [-0.532681, 'foo', 0],
    [1.490752, 'bar', 1],
    [-1.387326, 'fo o', 2],
    [0.814772, 'baz', ' '],     
    [-0.222552, '   ', 4],
    [-1.176781,  'qux', ''],         
], columns='A B C'.split(), index=pd.date_range('2000-01-01','2000-01-06'))

Notez également que "fo o" n'est pas remplacé par Nan, même s'il contient un espace. Notez également qu'un simple :

df.replace(r'', np.NaN)

Ne fonctionne pas non plus - essayez-le.

40voto

BrenBarn Points 63718

Pourquoi pas :

d = d.applymap(lambda x: np.nan if isinstance(x, basestring) and x.isspace() else x)

El applymap applique une fonction à chaque cellule du cadre de données.

35voto

Xiaorong Liao Points 671

J'ai fait ça :

df = df.apply(lambda x: x.str.strip()).replace('', np.nan)

ou

df = df.apply(lambda x: x.str.strip() if isinstance(x, str) else x).replace('', np.nan)

Vous pouvez enlever toutes les chaînes, puis remplacer les chaînes vides par np.nan .

10voto

ibrahim rupawala Points 101

Si vous exportez les données du fichier CSV, cela peut être aussi simple que ceci :

df = pd.read_csv(file_csv, na_values=' ')

Cela créera le cadre de données et remplacera les valeurs vides comme Na

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X