如何从NumPy数组中删除NaN值?
[1, 2, NaN, 4, NaN, 8] ⟶ [1, 2, 4, 8]
从NumPy数组x
中删除NaN值:
x = x[~numpy.isnan(x)]
内部函数numpy.isnan
返回一个布尔/逻辑数组,其中每个值为True
表示对应的x
不是数字。由于我们想要相反的结果,因此我们使用逻辑非运算符~
获取一个数组,其中每个值为True
表示对应的x
是有效的数字。
最后,我们使用这个逻辑数组来索引原始数组x
,以仅检索非NaN值。
filter(lambda v: v==v, x)
该函数适用于列表和numpy数组,因为v!= v仅适用于NaN。
x[~numpy.isnan(x)]
相比,它可能会慢些。 - smm[v for v in var if v == v]
。 - Darren Weber对我来说,@jmetz的答案不起作用,但使用pandas的isnull()函数解决了问题。
x = x[~pd.isnull(x)]
x = x[x.notnull()]
- kbridge4096TypeError: ufunc 'isnan' not supported for the input types
错误。它不能处理字符串或对象类型。而这个解决方案可以。 - Llohannprint([value for value in x if not math.isnan(value)])
- hypersnp
包中的列表推导式回答:因此,返回不带nans的列表:[value for value in x if not np.isnan(value)]
- yeliabsalohcin正如其他人所展示的那样
x[~numpy.isnan(x)]
它可以工作。但是,如果numpy的dtype不是本地数据类型(例如,如果它是对象),它将抛出一个错误。在这种情况下,您可以使用pandas。
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]
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='')
Result:
==================== 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.]
如果有所帮助的话,对于简单的一维数组:
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)
,因为它效率低下。
x = x[~numpy.isnan(x)]
或者
x = x[numpy.logical_not(numpy.isnan(x))]
我发现将同一变量(x)重置并不能移除实际的nan值,必须使用不同的变量。将其设置为不同的变量可以移除nan。
例如:y = x[~numpy.isnan(x)]
x
(即不带NaN的值...)。您能否提供更多信息,以说明可能发生了什么? - jmetz
x
中所有的非有限数值去除,并重新赋值给x
。可以用以下代码实现:x = x[numpy.isfinite(x)]
。 - Miki Tebekax = x[~numpy.isnan(x)]
,这与mutzmatron的原始回答是等效的,但更短。如果你想保留无穷大的值,应该知道numpy.isfinite(numpy.inf) == False
,当然,~numpy.isnan(numpy.inf) == True
。 - chbrownnp.where(np.isfinite(x), x, 0)
。 - BoltzmannBrainx
不是一个 numpy 数组。如果你想使用逻辑索引,它必须是一个数组 - 例如x = np.array(x)
。 - jmetz