如何从NumPy数组中删除NaN值?

如何从NumPy数组中删除NaN值?

[1, 2, NaN, 4, NaN, 8]   ⟶   [1, 2, 4, 8]
664269 次浏览

试试这个:

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

更多信息,请阅读列表理解

从NumPy数组x中移除NaN值:

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

内部函数numpy.isnan返回一个布尔/逻辑数组,在所有x不是数字的地方,该数组的值为True。因为我们想要相反的结果,所以我们使用非逻辑操作符~来获得一个数组,其中__abc1在所有x 为有效数字的地方。

最后,我们使用这个逻辑数组对原始数组x进行索引,以便只检索非nan值。

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

适用于列表和numpy数组 因为v !=v仅用于NaN

做到以上几点:

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

x = x[numpy.logical_not(numpy.isnan(x))]
我发现重置到相同的变量(x)没有删除实际的nan值,必须使用不同的变量。将其设置为不同的变量删除了nan。 例如< / p >
y = x[~numpy.isnan(x)]

对我来说,@jmetz的答案不工作,但是使用pandas isnull()做到了。

x = x[~pd.isnull(x)]

正如其他人所示

x[~numpy.isnan(x)]

的工作原理。但是如果numpy dtype不是原生数据类型(例如,如果它是object),它将抛出一个错误。在这种情况下,你可以用熊猫。

x[~pandas.isna(x)] or x[~pandas.isnull(x)]

如果你正在使用numpy

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


# second get the values
x = x[ii]
接受的答案改变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.]

@jmetz的回答可能是大多数人需要的;然而,它会产生一个一维数组,例如,使其无法用于删除矩阵中的整行或整列。

为此,应该将逻辑数组缩减为一维,然后对目标数组进行索引。例如,下面将删除至少有一个NaN值的行:

x = x[~numpy.isnan(x).any(axis=1)]

详见在这里

简单地填充

 x = numpy.array([
[0.99929941, 0.84724713, -0.1500044],
[-0.79709026, numpy.NaN, -0.4406645],
[-0.3599013, -0.63565744, -0.70251352]])


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


print(x)


# [[ 0.99929941  0.84724713 -0.1500044 ]
#  [-0.79709026  0.555      -0.4406645 ]
#  [-0.3599013  -0.63565744 -0.70251352]]

如果它有帮助,对于简单的1d数组:

x = np.array([np.nan, 1, 2, 3, 4])


x[~np.isnan(x)]
>>> array([1., 2., 3., 4.])

但如果你希望扩展到矩阵并保留形状:

x = np.array([
[np.nan, np.nan],
[np.nan, 0],
[1, 2],
[3, 4]
])


x[~np.isnan(x).any(axis=1)]
>>> array([[1., 2.],
[3., 4.]])

我在处理pandas .shift()功能时遇到了这个问题,并且由于其效率低下,我想不惜一切代价避免使用.apply(..., axis=1)

Pandas引入了一个将所有数据类型转换为缺失值的选项。

np.isnan()函数不兼容所有的数据类型,例如:

>>> import numpy as np
>>> values = [np.nan, "x", "y"]
>>> np.isnan(values)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
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''

pd.isna()pd.notna()函数与许多数据类型兼容,pandas引入了一个pd.NA值:

>>> import numpy as np
>>> import pandas as pd


>>> values = pd.Series([np.nan, "x", "y"])
>>> values
0    NaN
1      x
2      y
dtype: object
>>> values.loc[pd.isna(values)]
0    NaN
dtype: object
>>> values.loc[pd.isna(values)] = pd.NA
>>> values.loc[pd.isna(values)]
0    <NA>
dtype: object
>>> values
0    <NA>
1       x
2       y
dtype: object


#
# using map with lambda, or a list comprehension
#


>>> values = [np.nan, "x", "y"]
>>> list(map(lambda x: pd.NA if pd.isna(x) else x, values))
[<NA>, 'x', 'y']
>>> [pd.NA if pd.isna(x) else x for x in values]
[<NA>, 'x', 'y']