Как я могу получить все индексы всех NaN в списке? - PullRequest
1 голос
/ 17 мая 2019

Я пытаюсь создать список с индексом всех NaNs в списке a.

Проблема в том, что список ind не заполнен ничем.Это работает, если вместо NaN я добавлю случайную строку вроде c.

import numpy as np

a=[1, 2, 3, 4, np.nan, np.nan, 2, np.nan]

ind=[]
for i in range(0,len(a)):

    if a[i]==float("NaN"):
        ind.append(i)
print ind

Ответы [ 2 ]

1 голос
/ 17 мая 2019

Используйте np.nan для сравнения

import numpy as np

a=[1,2,3,4,np.nan,np.nan,2,np.nan]

ind=[]
for i in range(0,len(a)):
    if a[i] is np.nan:
        ind.append(i)
print ind

выход

[4, 5, 7]

Использование списка понимания:

[x  for x in range(0,len(a)) if a[x] is np.nan]

В качестве альтернативы, если вы построили массив с использованием numpy-функций, используйте для сравнения np.isnan(a[i]).

0 голосов
/ 17 мая 2019

Если вы используете NumPy, вам действительно следует начать использовать массивы и избавиться от привычки зацикливаться вручную на уровне Python. Ручные циклы обычно примерно в 100 раз медленнее, чем NumPy, и списки с плавающей запятой занимают примерно в 4 раза больше памяти массива.

В этом случае NumPy может дать вам массив индексов NaN довольно просто:

ind = numpy.where(numpy.isnan(a))[0]

numpy.isnan дает массив логических значений, указывающих, какие элементы a являются NaN. numpy.where дает массив индексов True элементов, но обернут в 1-элементный кортеж для согласованности с поведением многомерных массивов, поэтому [0] извлекает массив из кортежа.

Это работает, когда a является списком, но вы действительно должны использовать массивы.


Ваша попытка не удалась, потому что значения NaN не равны друг другу или самим себе:

>>> numpy.nan == numpy.nan
False
>>> numpy.nan == float('nan')
False

NaN был разработан таким образом для алгоритмического удобства, чтобы сделать x != x простой проверкой значений NaN в средах, где создание NaN для сравнения неудобно, и потому что NaN имеют редко используемую полезную нагрузку компонент, который может быть различным у разных NaN.


Другой ответ рекомендует тест is numpy.nan, но он ошибочен и ненадежен. Это работает только в том случае, если ваши NaN являются определенным объектом numpy.nan, что редко бывает:

>>> float('nan') is numpy.nan
False
>>> numpy.float64(0)/0 is numpy.nan
__main__:1: RuntimeWarning: invalid value encountered in double_scalars
False
>>> numpy.array([numpy.nan])[0] is numpy.nan
False

Положитесь на is numpy.nan чеков, и они будут кусать вас.

...