311

我想弄清楚如何从我的数组中删除 nan 值。我的数组看起来像这样:

x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration

如何从中删除nanx

4

12 回答 12

477

如果您对数组使用 numpy,您也可以使用

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

等效地

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

[感谢 chbrown 添加的速记]

解释

内部函数numpy.isnan返回一个布尔/逻辑数组,该数组在True任何地方都x具有非数字的值。正如我们想要的相反,我们使用逻辑非运算符~来获得一个数组,其中Trues 到处都是x 有效数字。

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

于 2012-07-23T21:42:30.267 回答
67
filter(lambda v: v==v, x)

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

于 2015-04-16T15:46:36.443 回答
36

试试这个:

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

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

于 2012-07-23T21:39:59.420 回答
32

对我来说,@jmetz 的答案没有用,但是使用 pandas isnull() 可以。

x = x[~pd.isnull(x)]
于 2017-04-18T14:37:51.067 回答
7

正如其他人所展示的

x[~numpy.isnan(x)]

作品。但是如果 numpy dtype 不是本机数据类型,例如它是对象,它将引发错误。在这种情况下,您可以使用熊猫。

x[~pandas.isna(x)] or x[~pandas.isnull(x)]
于 2017-11-25T12:55:01.577 回答
7

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

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

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

在此处查看更多详细信息。

于 2020-05-04T09:43:05.117 回答
6

执行上述操作:

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

或者

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

我发现重置为相同的变量 (x) 并没有删除实际的 nan 值,并且必须使用不同的变量。将其设置为不同的变量会删除 nans。例如

y = x[~numpy.isnan(x)]
于 2016-06-23T20:35:51.397 回答
6

如果你正在使用numpy

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

# second get the values
x = x[ii]
于 2018-02-16T09:19:02.433 回答
6

接受的答案改变了二维数组的形状。我在这里提出了一个解决方案,使用 Pandas dropna()功能。它适用于一维和二维数组。在 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.]
于 2019-03-16T06:37:23.617 回答
3

如果有帮助,对于简单的一维数组:

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)

于 2021-03-15T18:36:11.117 回答
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]]
于 2020-12-18T10:08:48.947 回答
0

一个最简单的方法是:

numpy.nan_to_num(x)

文档:https ://docs.scipy.org/doc/numpy/reference/generated/numpy.nan_to_num.html

于 2017-06-21T18:03:06.630 回答