在 nanmax 中指定轴时出现 Numpy 错误,而 nansum 在相同情况下工作

Numpy error when specifying axis in nanmax while nansum works an the same case

我正在尝试获取 numpy.arrays 的最大值,如以下代码所示:

[np.nanmax(temp_data[i:i+window_size, 1:], axis=0) for i, t in enumerate(temp_data)]

不过,我收到以下错误:

{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''

无论如何,如果我使用 nansum 而不是 nanmax,就像下面的代码一样,一切都会顺利进行:

[np.nansum(temp_data[i:i+window_size, 1:], axis=0) for i, t in enumerate(temp_data)]
=> A 9x2 requested np.array

此外,这对代码来说,nanmaxnansum 都有效:

[np.nansum(temp_data[i:i+window_size, 1:]) for i, t in enumerate(temp_data)]
[np.nanmax(temp_data[i:i+window_size, 1:]) for i, t in enumerate(temp_data)]
=> A 9x1 np.array, (but this is not what I want)

知道吗,为什么在 nanmax 中指定轴失败,而它适用于 nansum

编辑:temp_data 的示例:

    temp_data = np.array([[datetime.datetime(1980, 1, 1, 0, 0), np.nan, np.nan],
                          [datetime.datetime(1980, 1, 2, 0, 0), np.nan, np.nan],
                          [datetime.datetime(1980, 1, 3, 0, 0), np.nan, np.nan],
                          [datetime.datetime(1980, 1, 4, 0, 0), np.nan, np.nan],
                          [datetime.datetime(1980, 1, 7, 0, 0), np.nan, 1],
                          [datetime.datetime(1980, 1, 8, 0, 0), np.nan, 2],
                          [datetime.datetime(1980, 1, 9, 0, 0), 1, 3],
                          [datetime.datetime(1980, 1, 10, 0, 0), 5, 4],
                          [datetime.datetime(1980, 1, 11, 0, 0), 4, 1]])

您可以强制对数据进行 float 转换,因为 numpy 似乎不知道如何处理具有 object 类型的数据:

#                                              \/
>>> [np.nanmax(temp_data[i:i+window_size, 1:].astype(float), axis=0) for i, t in enumerate(temp_data)]
[array([ nan,  nan]),
 array([ nan,  nan]),
 array([ nan,  nan]),
 array([ nan,   1.]),
 array([ nan,   2.]),
 array([ 1.,  3.]),
 array([ 5.,  4.]),
 array([ 5.,  4.]),
 array([ 4.,  1.])]

这是 numpy 中的错误或未定义行为的结果。您的数组 temp_data 具有数据类型 object。这意味着数组中的值可以是任意 Python 个对象。您看到的错误是将对象数组提供给 nanmax 并指定轴时发生的情况。

这是一个简单的例子,使用 numpy 版本 1.12.1:

In [21]: a = np.array([[1.0, 2.0], [3.0, 4.0]], dtype=object)

In [22]: np.nanmax(a, axis=0)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-22-a020f98a2536> in <module>()
----> 1 np.nanmax(a, axis=0)

/Users/warren/miniconda3scipy/lib/python3.5/site-packages/numpy/lib/nanfunctions.py in nanmax(a, axis, out, keepdims)
    343         # Fast, but not safe for subclasses of ndarray
    344         res = np.fmax.reduce(a, axis=axis, out=out, **kwargs)
--> 345         if np.isnan(res).any():
    346             warnings.warn("All-NaN slice encountered", RuntimeWarning, stacklevel=2)
    347     else:

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''

未指定 axis 时函数不会引发错误`:

In [23]: np.nanmax(a)
Out[23]: 4.0

nansum() 正确处理轴:

In [24]: np.nansum(a, axis=0)
Out[24]: array([4.0, 6.0], dtype=object)

如果数组中的对象都可以转换为Python浮点值,则可以使用astype()方法将数组转换为数据类型为numpy.float64的数组,因为nanmax() 按预期工作:

In [26]: a.astype(np.float64)
Out[26]: 
array([[ 1.,  2.],
       [ 3.,  4.]])

In [27]: np.nanmax(a.astype(np.float64), axis=0)
Out[27]: array([ 3.,  4.])