it-roy-ru.com

Удаление значений Nan из массива

Я хочу выяснить, как удалить значения Nan из моего массива. Это выглядит примерно так: 

x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration

Я относительно новичок в Python, поэтому я все еще учусь. Какие-нибудь советы?

148
Dax Feliz

Если вы используете NumPy для своих массивов, вы также можете использовать

x = x[numpy.logical_not(numpy.isnan(x))]

Эквивалентно 

x = x[~numpy.isnan(x)]

[Спасибо chbrown за добавленную стенографию] 

Объяснение

Внутренняя функция numpy.isnan возвращает логический/логический массив со значением True везде, где x не является числом. Поскольку мы хотим обратного, мы используем оператор логического not, ~, чтобы получить массив с Trues везде, где x is valid число.

Наконец, мы используем этот логический массив для индексации в исходный массив x, чтобы получить только значения, отличные от NaN.

261
jmetz
filter(lambda v: v==v, x)

работает как для списков, так и для массива numpy , так как v! = v только для NaN

39
udibr

Попробуй это:

import math
print [value for value in x if not math.isnan(value)]

Подробнее читайте в Список понятий .

32
liori

Для меня ответ @jmetz не сработал, однако использование pandas isnull () сработало.

x = x[~pd.isnull(x)]
12
Daniel Kislyuk

Делать выше:

x = x[~numpy.isnan(x)]

или же

x = x[numpy.logical_not(numpy.isnan(x))]

Я обнаружил, что сброс к той же самой переменной (x) не удаляет фактические значения nan и должен был использовать другую переменную. Установка его в другую переменную удалила nans . Например. 

y = x[~numpy.isnan(x)]
6
melissaOu

Как показали другие 

x[~numpy.isnan(x)]

работает. Но он выдаст ошибку, если numpy dtype не является собственным типом данных, например, если это object. В этом случае вы можете использовать панд.

x[~pandas.isnan(x)]
2
koliyat9811

Если вы используете numpy 

# first get the indices where the values are finite
ii = np.isfinite(x)

# second get the values
x = x[ii]
1
aloha

принятый ответ меняет форму для 2d массивов. Я представляю решение здесь, используя функциональность Pandas dropna () . Работает для 1D и 2D массивов. В 2D-случае вы можете выбрать погоду, чтобы отбросить строку или столбец , содержащий np.nan.

import pandas as pd
import numpy as np

def dropna(arr, *args, **kwarg):
    assert isinstance(arr, np.ndarray)
    dropped=pd.DataFrame(arr).dropna(*args, **kwarg).values
    if arr.ndim==1:
        dropped=dropped.flatten()
    return dropped

x = np.array([1400, 1500, 1600, np.nan, np.nan, np.nan ,1700])
y = np.array([[1400, 1500, 1600], [np.nan, 0, np.nan] ,[1700,1800,np.nan]] )


print('='*20+' 1D Case: ' +'='*20+'\nInput:\n',x,sep='')
print('\ndropna:\n',dropna(x),sep='')

print('\n\n'+'='*20+' 2D Case: ' +'='*20+'\nInput:\n',y,sep='')
print('\ndropna (rows):\n',dropna(y),sep='')
print('\ndropna (columns):\n',dropna(y,axis=1),sep='')

print('\n\n'+'='*20+' x[np.logical_not(np.isnan(x))] for 2D: ' +'='*20+'\nInput:\n',y,sep='')
print('\ndropna:\n',x[np.logical_not(np.isnan(x))],sep='')

Результат:

==================== 1D Case: ====================
Input:
[1400. 1500. 1600.   nan   nan   nan 1700.]

dropna:
[1400. 1500. 1600. 1700.]


==================== 2D Case: ====================
Input:
[[1400. 1500. 1600.]
 [  nan    0.   nan]
 [1700. 1800.   nan]]

dropna (rows):
[[1400. 1500. 1600.]]

dropna (columns):
[[1500.]
 [   0.]
 [1800.]]


==================== x[np.logical_not(np.isnan(x))] for 2D: ====================
Input:
[[1400. 1500. 1600.]
 [  nan    0.   nan]
 [1700. 1800.   nan]]

dropna:
[1400. 1500. 1600. 1700.]
0
Markus Dutschke

Это мой подход к фильтрации ndarray "X" для NaN и инф, 

Я создаю карту строк без NaN и inf следующим образом:

idx = np.where((np.isnan(X)==False) & (np.isinf(X)==False))

idx - это кортеж Второй столбец (idx[1]) содержит индексы массива, где ни NaN, ни inf не найдено в строке.

Затем:

filtered_X = X[idx[1]]

filtered_X содержит X без NaN и inf.

0
aerijman