Numpy isnan () не работает с массивом чисел с плавающей запятой (применяется из фрейма данных pandas)

105

У меня есть массив чисел с плавающей запятой (некоторые нормальные числа, некоторые nans), который выходит из приложения на фреймворке pandas.

По какой-то причине numpy.isnan не работает в этом массиве, однако, как показано ниже, каждый элемент является float, numpy.isnan работает правильно для каждого элемента, тип переменной определенно является массивом numpy.

В чем дело?!

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
источник

Ответы:

167

np.isnan может применяться к массивам NumPy собственного dtype (например, np.float64):

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

но вызывает TypeError при применении к массивам объектов:

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

Поскольку у вас есть Pandas, вы можете использовать pd.isnullвместо этого - он может принимать массивы объектов NumPy или собственные типы dtypes:

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)

Обратите внимание, что Noneэто также считается нулевым значением в массивах объектов.

Unutbu
источник
3
Спасибо - использовал pd.isnull (). На производительность тоже не влияет.
tim654321
12

Отличная замена для np.isnan () и pd.isnull () -

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

поскольку только nan не равен самому себе.

Стэтхэм
источник
это может не работать для массивов, так как вызывает хорошо известную ошибку ValueError: истинное значение xxx неоднозначно.
MSeifert
@MSeifert Вы говорите о питоне ? Я просто использую этот метод, чтобы что-то делать в машинном обучении. Почему я не столкнулся с известной ошибкой?
Стэтхэм
Да, похоже, вы раньше не использовали numpy или pandas. Просто используйте import numpy as np; a = np.array([1,2,3, np.nan])и запустите свой код.
MSeifert
@MSeifert er, я новичок в numpy, но код работал нормально, никаких ошибок не было
Стэтхэм
В [1]: импортировать numpy как np В [2]: a = np.array ([1,2,3, np.nan]) В [3]: вывести [1. 2. 3. nan] В [ 4]: выведите [3] == a [3] Неверно
Стэтхэм
10

В дополнение к ответу @unutbu вы можете принудить массив объектов pandas numpy к собственному типу (float64), что-то в строке

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

Укажите errors = 'coerce', чтобы строки, которые нельзя проанализировать до числового значения, стали NaN. Тип столбца будет dtype: float64, а затем isnanпроверка должна работать

Северин Паппадукс
источник
Его зовут вроде бы unutbu;)
Dr_Zaszuś
@ Dr_Zaszuś Спасибо, исправлено
Severin Pappadeux
1

Убедитесь, что вы импортируете файл csv с помощью Pandas

import pandas as pd

condition = pd.isnull(data[i][j])
Дарисван Янвери П.
источник