Numpy isnan () falha em um array de floats (do pandas dataframe se aplica)

101

Eu tenho uma matriz de flutuadores (alguns números normais, alguns nans) que está saindo de um aplicar em um dataframe do pandas.

Por alguma razão, numpy.isnan está falhando neste array, no entanto, conforme mostrado abaixo, cada elemento é um float, numpy.isnan é executado corretamente em cada elemento, o tipo da variável é definitivamente um array numpy.

O que está acontecendo?!

set([type(x) for x in tester])
Out[59]: {float}

tester
Out[60]: 
array([-0.7000000000000001, nan, nan, nan, nan, nan, nan, nan, nan, nan,
   nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
   nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
   nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
   nan, nan], dtype=object)

set([type(x) for x in tester])
Out[61]: {float}

np.isnan(tester)
Traceback (most recent call last):

File "<ipython-input-62-e3638605b43c>", line 1, in <module>
np.isnan(tester)

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''

set([np.isnan(x) for x in tester])
Out[65]: {False, True}

type(tester)
Out[66]: numpy.ndarray
tim654321
fonte

Respostas:

163

np.isnan pode ser aplicado a matrizes NumPy de dtype nativo (como np.float64):

In [99]: np.isnan(np.array([np.nan, 0], dtype=np.float64))
Out[99]: array([ True, False], dtype=bool)

mas gera TypeError quando aplicado a matrizes de objetos:

In [96]: np.isnan(np.array([np.nan, 0], dtype=object))
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''

Já que você tem Pandas, você pode usar em seu pd.isnulllugar - ele pode aceitar matrizes NumPy de objetos ou dtypes nativos:

In [97]: pd.isnull(np.array([np.nan, 0], dtype=float))
Out[97]: array([ True, False], dtype=bool)

In [98]: pd.isnull(np.array([np.nan, 0], dtype=object))
Out[98]: array([ True, False], dtype=bool)

Observe que Nonetambém é considerado um valor nulo em matrizes de objetos.

unutbu
fonte
3
Obrigado - usado pd.isnull (). Também não parece haver nenhum impacto no desempenho.
tim654321
11

Um ótimo substituto para np.isnan () e pd.isnull () é

for i in range(0,a.shape[0]):
    if(a[i]!=a[i]):
       //do something here
       //a[i] is nan

já que apenas nan não é igual a si mesmo.

Statham
fonte
isso pode não funcionar para arrays porque gera o conhecido "ValueError: O valor verdadeiro de um xxx é ambíguo".
MSeifert
@MSeifert Você está falando sobre python ? Acabei de usar esse método para fazer algo no aprendizado de máquina. Por que não encontrei o erro conhecido?
Statham
Sim, parece que você nunca usou numpy ou pandas antes. Basta usar import numpy as np; a = np.array([1,2,3, np.nan])e executar seu código.
MSeifert
@MSeifert er, eu sou novo no numpy, mas o código funcionou bem, nenhum erro ocorreu
Statham
In [1]: import numpy as np In [2]: a = np.array ([1,2,3, np.nan]) In [3]: imprima a [1. 2. 3. nan] In [ 4]: print a [3] == a [3] False
Statham
10

Além da resposta @unutbu, você poderia forçar a matriz de objetos numpy dos pandas para o tipo nativo (float64), algo ao longo da linha

import pandas as pd
pd.to_numeric(df['tester'], errors='coerce')

Especifique errors = 'coerce' para forçar strings que não podem ser analisadas para um valor numérico se tornarem NaN. O tipo de coluna seria dtype: float64, e a isnanverificação deve funcionar

Severin Pappadeux
fonte
O nome dele parece ser unutbu;)
Dr_Zaszuś
@ Dr_Zaszuś Obrigado, corrigido
Severin Pappadeux
0

Certifique-se de importar o arquivo csv usando o Pandas

import pandas as pd

condition = pd.isnull(data[i][j])
Dariswan Janweri P.
fonte