在 dtype obj 的 NumPy 数组中查找缺失值

Posted

技术标签:

【中文标题】在 dtype obj 的 NumPy 数组中查找缺失值【英文标题】:Find missing values in NumPy array of dtype obj 【发布时间】:2014-11-03 09:01:09 【问题描述】:

我被一个 dtype obj 的 NumPy 数组和一个缺失值逼疯了(在下面的示例中,它是倒数第二个值)。

>> a
array([0, 3, 'Braund, Mr. Owen Harris', 'male', 22.0, 1, 0, 'A/5 21171',
       7.25, nan, 'S'], dtype=object)

我想通过一个函数以编程方式找到这个缺失值,该函数返回一个布尔向量,其中包含与数组中缺失值相对应的元素中的 True 值(如下例所示)。

>> some_function(a)
array([False, False, False, False, False, False, False, False, False, True, False],
      dtype=bool)

我试过isnan无济于事。

>> isnan(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not
be safely coerced to any supported types according to the casting rule ''safe''

我还尝试使用 apply_along_axis 对数组的每个元素显式执行操作,但返回相同的错误。

>> apply_along_axis(isnan, 0, a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not
be safely coerced to any supported types according to the casting rule ''safe''

谁能向我解释 (1) 我做错了什么以及 (2) 我可以做些什么来解决这个问题?从错误中,我推测它与其中一个元素的类型不合适有关。解决此问题的最简单方法是什么?

【问题讨论】:

我不认为你可以'nan'一个对象 你的意思是isnan一个对象? 如果您要查找的nans 仅限于该列,您可以在应用isnan 之前对数组进行切片或索引。您也可以考虑使用 structured array 而不是对象数组。 【参考方案1】:

我建议使用Pandas.isna。与lumpy中对应的函数不同,这个版本处理缺失的字符串值。

s = np.array(['one', 'two', None, 'four'])
pd.isna(s)

输出:

array([False, False,  True, False])

【讨论】:

【参考方案2】:

另一种解决方法是:

In [148]: [item != item for item in a]
Out[148]: [False, False, False, False, False, False, False, False, False, True, False]

因为NaNs are not equal to themselves。但是请注意,可以定义自定义对象,如 NaN,不等于自身:

class Foo(object):
    def __cmp__(self, obj):
        return -1
foo = Foo()
assert foo != foo

所以使用item != item 并不一定意味着item 是一个NaN。


请注意,如果可能,最好避免使用 dtype object 的 NumPy 数组。

它们不是特别快——对其内容的操作 通常会演变为对底层 Python 对象的 Python 调用。一个正常的 Python 列表通常具有更好的性能。 与比 Python 数字列表更节省空间的数值数组不同,对象数组并不是特别节省空间,因为每个项目都是 对 Python 对象的引用。 它们也不是特别方便,因为许多 NumPy 操作 不适用于 dtype object 的数组。 isnan 就是这样一个例子。

【讨论】:

感谢您的回答!只是好奇,如果您不推荐 dtype object 的 NumPy 数组,您建议存储混合数据(即数字和字符串)什么? 我会使用 Python 列表或元组。【参考方案3】:

我想通了!列表理解是要走的路。

问题源于不能在字符串上调用isnan。因此,诀窍是遍历元素,对任何非字符串类型的元素执行isnan 操作。

[isnan(i) if type(i) != str else False for i in a]

【讨论】:

以上是关于在 dtype obj 的 NumPy 数组中查找缺失值的主要内容,如果未能解决你的问题,请参考以下文章

如何转换numpy子数组的dtype?

如何在我的 numpy 数组中找到 NaN/infinity/对于 dtype('float64') 来说太大的值?

numpy 数组 dtype 在 Windows 10 64 位机器中默认为 int32

如何将numpy数组中的相同元素移动到子数组中

为啥numpy在执行list方法时不创建数组

更改 dtype 时 Numpy 数组形状会发生变化