Я хочу выяснить, как удалить значения Nan из моего массива. Мой массив выглядит примерно так:
x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration
Как я могу удалить nan
значения из x
?
Я хочу выяснить, как удалить значения Nan из моего массива. Мой массив выглядит примерно так:
x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration
Как я могу удалить nan
значения из x
?
Ответы:
Если вы используете NumPy для своих массивов, вы также можете использовать
x = x[numpy.logical_not(numpy.isnan(x))]
эквивалентно
x = x[~numpy.isnan(x)]
[Спасибо chbrown за добавленную стенографию]
объяснение
Внутренняя функция numpy.isnan
возвращает логический / логический массив, значение которого True
везде x
не является числом. Поскольку мы хотим обратного, мы используем оператор логического not, ~
чтобы получить массив с True
s везде, который x
является допустимым числом.
Наконец, мы используем этот логический массив для индексации в исходном массиве x
, чтобы получить только значения, отличные от NaN.
x = x[numpy.isfinite(x)]
x = x[~numpy.isnan(x)]
, что эквивалентно первоначальному ответу mutzmatron, но короче. Если вы хотите сохранить свою бесконечность, знайте numpy.isfinite(numpy.inf) == False
, конечно, но ~numpy.isnan(numpy.inf) == True
.
np.where(np.isfinite(x), x, 0)
x
не являются массивом. Если вы хотите использовать логический индексирование, он должен быть массив - напримерx = np.array(x)
filter(lambda v: v==v, x)
работает как для списков, так и для массива numpy, поскольку v! = v только для NaN
x
быть указано только один раз, в отличие от решений типа x[~numpy.isnan(x)]
. Это удобно, когда x
определяется длинным выражением, и вы не хотите загромождать код, создавая временную переменную для хранения результата этого длинного выражения.
Попробуй это:
import math
print [value for value in x if not math.isnan(value)]
Для получения дополнительной информации читайте в Списке понятий .
print ([value for value in x if not math.isnan(value)])
np
пакетом: Итак, возвращает ваш список без nans:[value for value in x if not np.isnan(value)]
Для меня ответ @jmetz не сработал, однако использование pandas isnull () сработало.
x = x[~pd.isnull(x)]
Делаем выше:
x = x[~numpy.isnan(x)]
или
x = x[numpy.logical_not(numpy.isnan(x))]
Я обнаружил, что сброс к той же самой переменной (x) не удаляет фактические значения nan и должен был использовать другую переменную. Установка его в другую переменную удалила nans. например
y = x[~numpy.isnan(x)]
x
перезаписывать новое значение (т. е. без NaNs ...) , Можете ли вы предоставить больше информации о том, почему это может происходить?
Как показали другие
x[~numpy.isnan(x)]
работает. Но он выдаст ошибку, если numpy dtype не является собственным типом данных, например, если это объект. В этом случае вы можете использовать панд.
x[~pandas.isna(x)] or x[~pandas.isnull(x)]
Общепринятый ответ меняет форму для 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.]
Самый простой способ это:
numpy.nan_to_num(x)
Документация: https://docs.scipy.org/doc/numpy/reference/generated/numpy.nan_to_num.html.
NaN
s большим числом, в то время как OP попросил полностью удалить элементы.
Это мой подход к фильтрации ndarray "X" для NaNs и Infs,
Я создаю карту строк без каких- 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
.
@ jmetz's answer вероятно, тот, который нужен большинству людей; однако он дает одномерный массив, например, делает невозможным удаление целых строк или столбцов в матрицах.
Для этого следует уменьшить логический массив до одного измерения, а затем проиндексировать целевой массив. Например, следующее удалит строки, которые имеют хотя бы одно значение NaN:
x = x[~numpy.isnan(x).any(axis=1)]
Подробнее смотрите здесь .