从数组中删除nan值

时间:2012-07-23 21:36:54

标签: python arrays numpy nan

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

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

我对python比较陌生,所以我还在学习。有什么提示吗?

13 个答案:

答案 0 :(得分:276)

如果你正在为数组使用numpy,你也可以使用

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

等价

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

[感谢chbrown增加的简写]

<强>解释

内部函数numpy.isnan返回一个布尔/逻辑数组,其值True到处x不是数字。正如我们所希望的那样,我们使用逻辑非运算符~来获取True 有效数字的x个数组。< / p>

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

答案 1 :(得分:40)

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

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

答案 2 :(得分:32)

试试这个:

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

有关详情,请参阅List Comprehensions

答案 3 :(得分:13)

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

mat-color

答案 4 :(得分:6)

执行以上操作:

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

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

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

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

答案 5 :(得分:3)

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

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

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

查看更多详细信息here

答案 6 :(得分:2)

如其他人所示

x[~numpy.isnan(x)]

的工作原理。但是如果numpy dtype不是本机数据类型,它会抛出错误,例如,如果它是对象。在这种情况下,您可以使用pandas。

x[~pandas.isnan(x)]

答案 7 :(得分:1)

如果您使用的是numpy

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

# second get the values
x = x[ii]

答案 8 :(得分:1)

只需填充

todoitemsListview.setCellFactory(new Callback<ListView<ToDoItems>, ListCell<ToDoItems>>() {
    @Override
    public ListCell<ToDoItems> call(ListView<ToDoItems> toDoItemsListView) {
        ListCell<ToDoItems> cell = new ListCell<ToDoItems>() {
            @Override
            protected void updateItem(ToDoItems items, boolean empty) {
                super.updateItem(items, empty);
                if (empty) {
                    setText(null);
                    setTextFill(Color.BLACK);
                } else {
                    setText(items.getItemName());
                    if (items.getDeadline().equals(LocalDate.now())) {
                        System.out.println(items.getDeadline().toString());
                        System.out.println(items.getItemName());
                        setTextFill(Color.RED);
                    } else if (items.getDeadline().equals(LocalDate.now().plusDays(1))) {
                        System.out.println(items.getDeadline().toString());
                        System.out.println(items.getItemName());
                        setTextFill(Color.BLUE);
                    } else if (items.getDeadline().equals(LocalDate.now().plusDays(2))) {
                        System.out.println(items.getDeadline().toString());
                        System.out.println(items.getItemName());
                        setTextFill(Color.GREEN);
                    } else if (items.getDeadline().isBefore(LocalDate.now())) {
                        System.out.println(items.getDeadline().toString());
                        System.out.println(items.getItemName());
                        setTextFill(Color.GREY);
                    } else {
                        setTextFill(Color.BLACK);
                    }
                }
            }
        };
        return cell;
    }
});

答案 9 :(得分:0)

这是我为NaN和infs过滤 ndarray “ X”的方法,

我创建的行映射不包含任何NaN和任何inf,如下所示:

idx = np.where((np.isnan(X)==False) & (np.isinf(X)==False))

idx是一个元组。它的第二列(idx[1])包含数组的索引,在该行中找不到 NaN inf

然后:

filtered_X = X[idx[1]]

filtered_X包含X个而没有 NaNinf

答案 10 :(得分:0)

accepted answer更改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='')

结果:

==================== 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.]

答案 11 :(得分:0)

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

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),因为它效率低下。

答案 12 :(得分:-2)

最简单的方法是:

numpy.nan_to_num(x)

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