我从 scipy/numpy 得到一些奇怪的行为,我怀疑这是一个错误,但有人可能知道得更多?我有一对长数组,为了调试目的,我将它们分成长度为 2-4 的帧。我想标准化每对帧并取点积。执行此操作的代码(带有一些调试输出)是:
tf = numpy.copy(t_frame) / norm(t_frame)
pf = numpy.copy(p_frame) / norm(p_frame)
print "OPF:"
print p_frame
print "PF: "
print pf
print "TF norm is: " + str(norm(tf))
print "PF norm is: " + str(norm(pf))
print numpy.dot(tf, pf)
return numpy.dot(tf, pf)
这确实符合我一段时间的预期(特别是为 tf 和 pf 指定了 1 的范数)但随后我开始看到这样的行:
OPF:
[ -91 -119 -137 -132]
PF:
[ nan nan nan nan]
什么?这可以在新的 Python 窗口中正常化:
>>> p = [ -91, -119, -137, -132]
>>> p / norm(p)
array([-0.37580532, -0.49143773, -0.56577285, -0.54512421])
对于它的值(value),我尝试了 numpy.linalg.norm、scipy.linalg.norm,并定义了一个函数来返回点的平方根产品。
有什么想法吗?
更新: 感谢您的建议!我尝试将 dtype 切换为 float128 并且很遗憾地得到了类似的行为。我实际上倾向于相信这是 Python 中的错误,而不是 numpy 在这一点上:
- 如果这是一个简单的溢出问题,我似乎会按照给定的列表得到它。但是,如果我在新的 Python session 中执行此操作,则规范计算得很好。
我尝试自己滚动:
def norm(v): return ( sum(numpy.array(v)*numpy.array(v)))**(0.5)这仅使用 numpy 来表示数组。我仍然遇到同样的问题,但是 稍后 在数据集中(并且没有运行时警告)。它正在执行大约 37000 次这样的计算。
- 我实际上是在计算两个帧的范数,一个 t_frame 和一个 p_frame。当且仅当另一个计算阻塞时,一个计算阻塞。
放在一起,我认为在 Python (2.7.9) 的内部某处存在一些奇怪的缓冲区溢出???我最终也需要这些计算速度快;所以我正在考虑切换到 Cython 进行计算。
更新 2: 我试着自己动手:
def norm(v):
sum = float(0)
for i in range(len(v)):
sum += v[i]**2
return sum**(0.5)
然后问题就消失了。所以我猜测它是 numpy(Gentoo Linux 上的 1.9.0)中的错误。
请您参考如下方法:
看起来这是 numpy 中的一个错误。如果数组的数据类型是 np.int16,我可以重现问题:
In [1]: np.__version__
Out[1]: '1.9.2'
In [2]: x = np.array([ -91, -119, -137, -132], dtype=np.int16)
In [3]: x
Out[3]: array([ -91, -119, -137, -132], dtype=int16)
In [4]: np.linalg.norm(x)
/Users/warren/anaconda/lib/python2.7/site-packages/numpy/linalg/linalg.py:2061: RuntimeWarning: invalid value encountered in sqrt
return sqrt(sqnorm)
Out[4]: nan
问题也出现在numpy开发版的master分支。我在这里创建了一个问题:https://github.com/numpy/numpy/issues/6128
如果 p_frame 实际上是一个 16 位整数数组,一个简单的解决方法如下:
x = np.asarray(p_frame, dtype=np.float64)
pf = x / norm(x)
