Python 从数组中删除nan值

Python 从数组中删除nan值,python,arrays,numpy,nan,Python,Arrays,Numpy,Nan,我想知道如何从数组中删除nan值。我的数组如下所示: x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration 如何从x中删除nan值?尝试以下操作: import math print [value for value in x if not math.isnan(value)] 有关更多信息,请继续阅读。如果您对阵列使用numpy,也可以使用 x = x[numpy.logical_not(n

我想知道如何从数组中删除nan值。我的数组如下所示:

x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration
如何从
x
中删除
nan
值?

尝试以下操作:

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

有关更多信息,请继续阅读。

如果您对阵列使用numpy,也可以使用

x = x[numpy.logical_not(numpy.isnan(x))]
等价地

x = x[~numpy.isnan(x)]
[感谢chbrown添加的速记]

解释

内部函数
numpy.isnan
返回一个布尔/逻辑数组,该数组在
x
不是数字的地方都有值
True
。由于我们想要相反的结果,我们使用逻辑not运算符,
~
来获得一个数组,其中
True
s在
x
是有效数字的地方

最后,我们使用这个逻辑数组索引到原始数组
x
,只检索非NaN值

filter(lambda v: v==v, x)
适用于列表和numpy数组 自从v=v仅适用于NaN执行上述操作:

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

我发现重置为同一个变量(x)并没有删除实际的nan值,必须使用不同的变量。将其设置为其他变量将删除NAN。 e、 g


对我来说,@jmetz的答案不起作用,但是使用pandas isnull()就起作用了

最简单的方法是:

numpy.nan_to_num(x)
文档:

如其他人所示

x[~numpy.isnan(x)]
工作。但如果numpy数据类型不是本机数据类型(例如,如果它是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]

这是我过滤NAN和INF的ndarray“X”的方法

我创建了一个没有任何
NaN
和任何
inf
的行映射,如下所示:

idx = np.where((np.isnan(X)==False) & (np.isinf(X)==False))
idx是一个元组。它的第二列(
idx[1]
)包含数组的索引,在该行中找不到NaN或inf

然后:

filtered_X
包含X而不包含
NaN
inf

二维数组的形状更改。 我在这里提出了一个解决方案,使用Pandas功能。 它适用于一维和二维阵列。在2D情况下,您可以选择weather以删除包含
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.]
可能是大多数人需要的;但是,它会生成一维数组,例如,无法删除矩阵中的整行或整列

为此,应将逻辑阵列缩减为一维,然后为目标阵列编制索引。例如,以下操作将删除至少具有一个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)]
>>>数组([1,2,3,4.]))
但如果您希望扩展到矩阵并保留形状:

x=np.array([
[np.nan,np.nan],
[np.nan,0],
[1, 2],
[3, 4]
])
x[~np.isnan(x).any(轴=1)]
>>>数组([[1,2.],
[3., 4.]])

我在处理pandas
.shift()
功能时遇到了这个问题,我想避免使用
.apply(…,axis=1)
,因为它效率低下。

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)
TypeError:只有整数标量数组才能转换为标量数组index@towry:发生这种情况是因为您的输入,
x
不是numpy数组。如果你想使用逻辑索引,它必须是一个数组-例如
x=np.array(x)
。不要忘记括号:)
print([value for value in x if not math.isnan(value)])
如果您像上面的答案一样使用numpy,那么您可以将此列表理解答案与
np
包一起使用:因此返回不带NaN的列表:
[value for value in x if not np.isnan(value)]
这是一种技巧,但在从混合类型的对象数组(如字符串和NaN)中筛选NaN时特别有用。非常干净的解决方案。这可能看起来很聪明,但如果模糊了逻辑和理论上的其他对象(如自定义类)也可以使此属性非常有用,因为它只需要指定一次
x
,而不是
x[~numpy.isnan(x)]
类型的解决方案。当
x
是由一个长表达式定义的,并且您不想通过创建一个临时变量来存储这个长表达式的结果来混乱代码时,这很方便。这可能比
x[~numpy.isnan(x)]
慢,这很奇怪;根据,布尔数组索引(即布尔数组索引)处于高级索引之下,显然“总是返回数据的副本”,因此您应该使用新值(即没有NAN…)过度写入
x
。你能提供更多关于为什么会发生这种情况的信息吗?欢迎来到SO!您提出的解决方案并没有解决问题:您的解决方案用一个大的数字替换
NaN
s,而OP要求完全删除元素。更清楚地说,“删除NaNs”是指只过滤掉非空值的子集。不是“用一些值(零、常数、平均值、中值等)填充NAN”
filtered_X = X[idx[1]]
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.]
 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]]