Я хочу розібратися, як видалити значення 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
не є a-число. Як ми хочемо навпаки, ми використовуємо логічний оператор, ~
щоб отримати масив з True
s всюди, що x
є дійсним числом.
Нарешті, ми використовуємо цей логічний масив для індексації у вихідний масив x
, щоб отримати лише не-NaN-значення.
x = x[numpy.isfinite(x)]
x = x[~numpy.isnan(x)]
, що еквівалентно оригінальній відповіді муцматрона, але коротше. Якщо ви хочете зберегти свої нескінченності навколо, знайте, що 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
пакетом: Тож повертає свій список без нан:[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 і довелося використовувати іншу змінну. Встановивши його на іншу змінну, вилучили нан. напр
y = x[~numpy.isnan(x)]
x
перезаписати з новим значенням (тобто без NaNs ...) . Чи можете ви надати більше інформації, чому це може статися?
Як показали інші
x[~numpy.isnan(x)]
працює. Але це призведе до помилки, якщо numtype dtype не є нативним типом даних, наприклад, якщо він є об'єктом. У такому випадку ви можете використовувати панди.
x[~pandas.isna(x)] or x[~pandas.isnull(x)]
Загальноприйнятий відповідь змінює форму для 2d масивів. Я представляю тут рішення, використовуючи функцію Pandas dropna () . Він працює для 1D і 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 великою кількістю, тоді як ОП просить повністю видалити елементи.
Це мій підхід до фільтрації ndarray "X" для NaNs та infs,
Я створюю карту рядків без будь-якого NaN
та будь-якого inf
наступного:
idx = np.where((np.isnan(X)==False) & (np.isinf(X)==False))
idx - кортеж. У другому стовпці ( idx[1]
) містяться індекси масиву, де в рядку немає NaN, ані інф .
Тоді:
filtered_X = X[idx[1]]
filtered_X
містить X без NaN
nor inf
.
@ відповідь jmetz - це, мабуть, саме той, хто найбільше потребує; однак він дає одновимірний масив, наприклад робить його непридатним для видалення цілих рядків або стовпців у матрицях.
Для цього слід зменшити логічний масив до одного виміру, а потім проіндексувати цільовий масив. Наприклад, нижче буде видалено рядки, які мають принаймні одне значення NaN:
x = x[~numpy.isnan(x).any(axis=1)]
Детальніше дивіться тут .