从数组中删除nan值

Dax*_*liz 188 python arrays numpy nan

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

x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration
Run Code Online (Sandbox Code Playgroud)

我对python比较陌生,所以我还在学习.有小费吗?

jme*_*etz 312

如果您正在为阵列使用numpy,您也可以使用

x = x[numpy.logical_not(numpy.isnan(x))]
Run Code Online (Sandbox Code Playgroud)

等价

x = x[~numpy.isnan(x)]
Run Code Online (Sandbox Code Playgroud)

[感谢chbrown增加的速记]

说明

内部函数numpy.isnan返回一个布尔/逻辑数组,该数组的值True到处x都是非数字.正如我们所希望的那样,我们使用logical-not运算符~来获取一个数组,其中包含True无处不x 的有效数字.

最后,我们使用此逻辑数组索引到原始数组x,以仅检索非NaN值.

  • 或者`x = x [numpy.isfinite(x)]` (27认同)
  • 或者`x = x [~numpy.isnan(x)]`,这相当于mutzmatron的原始答案,但更短.如果你想保持你的无穷大,知道`numpy.isfinite(numpy.inf)== False`,当然,但是`~numpy.isnan(numpy.inf)== True`. (14认同)
  • 寻找人与ndarray解决这个和维护方面,使用[numpy的地方(https://docs.scipy.org/doc/numpy/reference/generated/numpy.where.html):`np.where( np.isfinite(x),x,0)` (5认同)

udi*_*ibr 43

filter(lambda v: v==v, x)
Run Code Online (Sandbox Code Playgroud)

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

  • 一个hack,但是在你从具有混合类型的对象数组中过滤nans的情况下特别有用,例如字符串和nans. (5认同)
  • 这可能看起来很聪明,但如果模糊逻辑,理论上其他对象(如自定义类)也可以拥有此属性 (2认同)

lio*_*ori 32

试试这个:

import math
print [value for value in x if not math.isnan(value)]
Run Code Online (Sandbox Code Playgroud)

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

  • 如果你使用numpy我的答案和@ lazy1几乎比列表理解快一个数量级 - lazy1的解决方案稍快(虽然技术上也不会返回任何无穷大值). (4认同)

Dan*_*yuk 19

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

x = x[~pd.isnull(x)]
Run Code Online (Sandbox Code Playgroud)

  • 或者:`x = x[x.notnull()]` (2认同)

M4u*_*ice 7

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

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

x = x[~numpy.isnan(x).any(axis=1)]
Run Code Online (Sandbox Code Playgroud)

在此处查看更多详细信息


Rob*_*ens 7

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

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

x[~np.isnan(x)]
>>> array([1., 2., 3., 4.])
Run Code Online (Sandbox Code Playgroud)

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

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.]])
Run Code Online (Sandbox Code Playgroud)

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


小智 6

做到以上几点:

x = x[~numpy.isnan(x)]
Run Code Online (Sandbox Code Playgroud)

要么

x = x[numpy.logical_not(numpy.isnan(x))]
Run Code Online (Sandbox Code Playgroud)

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

y = x[~numpy.isnan(x)]
Run Code Online (Sandbox Code Playgroud)


kol*_*811 6

正如其他人所展示的

x[~numpy.isnan(x)]
Run Code Online (Sandbox Code Playgroud)

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

x[~pandas.isna(x)] or x[~pandas.isnull(x)]
Run Code Online (Sandbox Code Playgroud)


alo*_*oha 5

如果您正在使用 numpy

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

# second get the values
x = x[ii]
Run Code Online (Sandbox Code Playgroud)


Mar*_*hke 5

所述接受的答案改变为2D阵列的形状。我在这里提出了一个解决方案,使用 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='')
Run Code Online (Sandbox Code Playgroud)

结果:

==================== 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.]
Run Code Online (Sandbox Code Playgroud)