Controllare in modo efficiente se un oggetto arbitrario è NaN in Python / numpy / pandas?


101

I miei array numpy usano np.nanper designare i valori mancanti. Mentre itero sul set di dati, ho bisogno di rilevare tali valori mancanti e gestirli in modi speciali.

Ingenuamente ho usato numpy.isnan(val), che funziona bene a meno che valnon sia tra il sottoinsieme di tipi supportati da numpy.isnan(). Ad esempio, i dati mancanti possono verificarsi nei campi stringa, nel qual caso ottengo:

>>> np.isnan('some_string')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Not implemented for this type

Oltre a scrivere un involucro costoso che cattura l'eccezione e ritorna False, c'è un modo per gestirlo in modo elegante ed efficiente?


8
pandasha pandas.isnull(): non sono sicuro che soddisfi le tue esigenze, quindi alcuni dati di esempio potrebbero essere buoni.
Marius

4
@Mario: pandas.isnull()sembra funzionare perfettamente. L'unico tipo di dati con cui sto attualmente trattando che si interrompe numpy.isnan()è la stringa e lo pandas.isnull()gestisce bene. In effetti, sembra gestire bene tutti gli oggetti arbitrari che gli ho lanciato. C'erano problemi specifici di cui eri preoccupato? Altrimenti, potresti voler inviare il tuo commento come una risposta a tutti gli effetti, poiché sembra la risposta canonica, almeno per gli utenti di panda.
Dun Peal

Risposte:


169

pandas.isnull()(inoltre pd.isna(), nelle versioni più recenti) verifica la presenza di valori mancanti sia negli array numerici che in quelli di stringhe / oggetti. Dalla documentazione, verifica:

NaN negli array numerici, Nessuno / NaN negli array di oggetti

Esempio veloce:

import pandas as pd
import numpy as np
s = pd.Series(['apple', np.nan, 'banana'])
pd.isnull(s)
Out[9]: 
0    False
1     True
2    False
dtype: bool

L'idea di utilizzare numpy.nanper rappresentare i valori mancanti è qualcosa che ha pandasintrodotto, motivo per cui pandasha gli strumenti per affrontarlo.

Datetimes too (se usi pd.NaTnon dovrai specificare il dtype)

In [24]: s = Series([Timestamp('20130101'),np.nan,Timestamp('20130102 9:30')],dtype='M8[ns]')

In [25]: s
Out[25]: 
0   2013-01-01 00:00:00
1                   NaT
2   2013-01-02 09:30:00
dtype: datetime64[ns]``

In [26]: pd.isnull(s)
Out[26]: 
0    False
1     True
2    False
dtype: bool

19

Il tuo tipo è davvero arbitrario? Se sai che sarà solo un int float o una stringa, potresti semplicemente farlo

 if val.dtype == float and np.isnan(val):

supponendo che sia avvolto in numpy, avrà sempre un dtype e solo float e complex possono essere NaN


Ho a che fare con molti diversi tipi di dati. Mentre la maggior parte delle colonne ha tipi di dati int * o float *, altri potrebbero essere qualsiasi oggetto, sebbene finora l'unico altro tipo che ho usato fosse stringa.
Dun Peal

Le stringhe in Python non hanno dtype. Potrebbe essere necessario farlotype(val) == 'float'
pvarma

4
type(val) == float and np.isnan(val)- ha lavorato per me
Danny Cullen

@ user1930402 Presumo che questi siano array numpy non normali Python. Ad esempio: np.array (["hello"]) [0] .dtype funziona ma ["hello"] [0] .dtype no
Hammer
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.