问题 numpy.isfinite()中的意外异常


由于我不明白的原因,我得到了这个例外。这是非常复杂的,我的np.array v来自,但这是异常发生时的代码:

print v, type(v)

for val in v:
    print val, type(val)

print "use isfinte() with astype(float64): "
np.isfinite(v.astype("float64"))

print "use isfinite() as usual: "
try:
    np.isfinite(v)
except Exception,e:
    print e

这给出了以下输出:

[6.4441947744288255 7.2246449651781788 4.1028442021807656
 4.8832943929301189] <type 'numpy.ndarray'> 

6.44419477443 <type 'numpy.float64'>
7.22464496518 <type 'numpy.float64'>
4.10284420218 <type 'numpy.float64'>
4.88329439293 <type 'numpy.float64'>

np.isfinte() with astype(float64): 
[ True  True  True  True]

np.isfinte() as usual: 
ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

我不明白TypeError。所有元素都是np.float64,应该没问题。也许是个bug?此错误有时只会发生,但我无法找到数组之间的差异。总是有相同的类型。

提前致谢。

编辑:工作示例:

数据结构与上面显示的一样小。

import pandas as pd
import numpy as np


def forward_estim(H,end):

    old_idx = H.index
    new_idx = pd.period_range(old_idx[-1],end,freq=old_idx.freq)

    H_estim = pd.DataFrame(columns=["A","B","C","D"],index=new_idx)

    H_chg = H.values[1:]-H.values[:-1]
    mean_ = H_chg.mean()
    std_  = H_chg.std()

    H_estim.ix[0] = H.ix[-1]

    for i in range(1,len(H_estim)):
        H_estim.A[i] = H_estim.A[i-1] + mean_ + std_/2
        H_estim.B[i] = H_estim.B[i-1] + mean_ + std_
        H_estim.C[i] = H_estim.C[i-1] + mean_ - std_
        H_estim.D[i] = H_estim.D[i-1] + mean_ - std_/2

    return H_estim.ix[1:]


H_idx = pd.period_range("2010-01-01","2012-01-01",freq="A")
print H_idx

H = pd.Series(np.array([2.3,3.0,2.9]),index=H_idx)
print H

H_estim = forward_estim(H,"2014-01-01")
print H_estim

np.isfinite(H_estim.values.astype("float64"))
print "This works!"

np.isfinite(H_estim.values)
print "This does not work!"

这是在这里使用:

MacOsX Mavericks,Python 2.7.6,numpy 1.8.1,pandas 0.13.1


12100
2018-05-22 13:29


起源

你应该明确说明你在哪个系统上使用哪个版本的Python和numpy。如果你想出一个复制问题的最小例子,那将是非常有益的。 - Jan-Philip Gehrcke
用一个例子编辑了原始帖子。这将在我的机器/ python设置上抛出上面提到的异常。 - user2532323


答案:


H_estim.values 是一个数据类型的numpy数组 object (看一眼 H_estim.values.dtype):

In [62]: H_estim.values
Out[62]: 
array([[3.4000000000000004, 3.6000000000000005, 2.7999999999999998, 3.0],
       [3.9000000000000004, 4.3000000000000007, 2.6999999999999993,
        3.0999999999999996]], dtype=object)

In [63]: H_estim.values.dtype
Out[63]: dtype('O')

在一个 object 数组,存储在数组内存中的数据 指向python对象的指针而不是对象本身。在这种情况下,对象是 np.float64 实例:

In [65]: H_estim.values[0,0]
Out[65]: 3.4000000000000004

In [66]: type(H_estim.values[0,0])
Out[66]: numpy.float64

所以在很多方面,这个数组的外观和行为就像一个数组 np.float64 价值观,但不一样。特别是,numpy ufuncs(包括 np.isfinite)不处理对象数组。

H_estim.values.astype(np.float64) 将数组转换为具有数据类型的数组 np.float64 (即数组元素是实际浮点值的数组,而不是指向对象的指针)。将以下内容与上面显示的输出进行比较 H_estim.values

In [70]: a = H_estim.values.astype(np.float64)

In [71]: a
Out[71]: 
array([[ 3.4,  3.6,  2.8,  3. ],
       [ 3.9,  4.3,  2.7,  3.1]])

In [72]: a.dtype
Out[72]: dtype('float64')

10
2018-05-22 17:42



谢谢,沃伦。这很详细地回答了我的问题。添加我的问题:这是第二次使用.astype()可以绕过“意外”行为。 - user2532323
...那么,我是否在forward_estim()函数中做了一些概念上的错误,或者它是动态类型语言的缺点之一,你倾向于忽略/忘记考虑类型(和包装的“内部类型结构”)和像.astype()这样的“强制执行”命令只是你有时需要做的事情。这个函数属于大约10.000s代码行,到目前为止工作顺利。 - user2532323
对象数组由Pandas创建。 Pandas使用对象数组作为处理包含异构数据类型的数组的便捷方式,它通常工作正常,但有时,是的,你必须意识到它的局限性。顺便说一下,如果你正在使用 isfinite要检查NaN,您可以使用Pandas功能 isnull (pd.isnull,或DataFrame方法)。但 isnull 如果您正在检查,则无济于事 np.inf。 - Warren Weckesser
我使用DataFrame.dropna()很多,因为我的算法使用的底层数据库很大而且病得很重 - user2532323


你认为“所有元素都是np.float64,应该没问题。“但是,情况可能并非如此。数据结构有多大?你能看看所有的价值并找到可疑的东西吗?从 http://matplotlib.1069221.n5.nabble.com/type-error-with-python-3-2-and-version-1-1-1-of-matplotlib-numpy-error-td38784.html 我们看到这个问题可能会出现 Decimal 数据类型。有没有办法创建一个再现问题的最小工作示例?它应该是可能的,当你创建这个例子时,它很可能已经确定了问题。


1
2018-05-22 13:35



谢谢你的链接。在问之前我也发现了。这就是为什么我写了for循环打印数据的type()以确认它们是np.float64。这让我感到困惑,因为使用.astype(“float64”)会有所帮助,尽管数据已经是这种类型。 - user2532323