Python 规范化向量生成Numpy中的nan
我从scipy/numpy那里得到一些奇怪的行为,我怀疑这是一个bug,但有人可能知道得更清楚?我有一对长数组,为了调试的目的,我把它们分解成2-4的帧。我想标准化每一对帧,然后取点积。执行此操作的代码(带有一些调试输出)是: 这是我在一段时间内所期望的(特别是tf和pf的标准值为1),但随后我开始看到这样的线条: OPF: [-91-119-137-132] PF: [楠楠] 什么??这可以在新的Python窗口中正常化:Python 规范化向量生成Numpy中的nan,python,numpy,scipy,Python,Numpy,Scipy,我从scipy/numpy那里得到一些奇怪的行为,我怀疑这是一个bug,但有人可能知道得更清楚?我有一对长数组,为了调试的目的,我把它们分解成2-4的帧。我想标准化每一对帧,然后取点积。执行此操作的代码(带有一些调试输出)是: 这是我在一段时间内所期望的(特别是tf和pf的标准值为1),但随后我开始看到这样的线条: OPF: [-91-119-137-132] PF: [楠楠] 什么??这可以在新的Python窗口中正常化: >>> p = [ -91, -119, -137,
>>> p = [ -91, -119, -137, -132]
>>> p / norm(p)
array([-0.37580532, -0.49143773, -0.56577285, -0.54512421])
为了实现它的价值,我尝试了numpy.linalg.norm
,scipy.linalg.norm
,并定义了一个函数来返回点积的平方根
有什么想法吗
更新:
谢谢你的建议!我试着将数据类型切换到float128,但遗憾的是,我得到了类似的行为。实际上,我倾向于认为这是Python中的一个bug,而不是numpy中的bug:
def norm(v):
return ( sum(numpy.array(v)*numpy.array(v)))**(0.5)
def norm(v):
sum = float(0)
for i in range(len(v)):
sum += v[i]**2
return sum**(0.5)
这仅使用numpy表示数组。我仍然会遇到同样的问题,但稍后会出现在数据集中(并且没有运行时警告)。它正在进行大约37000次这样的计算def norm(v):
return ( sum(numpy.array(v)*numpy.array(v)))**(0.5)
def norm(v):
sum = float(0)
for i in range(len(v)):
sum += v[i]**2
return sum**(0.5)
问题消失了。所以我猜这是numpy中的一个bug(Gentoo Linux上的1.9.0)。看起来这是numpy中的一个bug。如果数组的数据类型为
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开发版本的主分支中。我在这里创建了一个问题:
如果p_frame
实际上是一个16位整数数组,那么简单的解决方法如下:
x = np.asarray(p_frame, dtype=np.float64)
pf = x / norm(x)
看起来这是numpy中的一个bug。如果数组的数据类型为
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开发版本的主分支中。我在这里创建了一个问题:
如果p_frame
实际上是一个16位整数数组,那么简单的解决方法如下:
x = np.asarray(p_frame, dtype=np.float64)
pf = x / norm(x)
根据沃伦的一个链接,我得到了以下警告:
In [1016]: np.linalg.norm(100000*np.ones(2).astype('int16'))
/usr/local/lib/python2.7/site-packages/numpy/linalg/linalg.py:2051: RuntimeWarning: invalid value encountered in sqrt
return sqrt(add.reduce((x.conj() * x).real, axis=None))
对于这个x2
,内部表达式是负数——这是小数据类型溢出的结果
In [1040]: x2=100000*np.ones(2).astype('int16')
In [1041]: np.add.reduce((x2.conj()*x2).real,axis=None)
Out[1041]: -1474836480
类似地,对于x1
:
In [1042]: x1
Out[1042]: array([ -9100, -11900, -13700, -13200], dtype=int16)
In [1043]: np.add.reduce((x1.conj()*x1).real,axis=None)
Out[1043]: -66128
如果“点”的总和对于dtype
来说太大,它可能是负数,在通过sqrt
时产生nan
(我在linux下使用的是1.8.2和1.9.0)。以下是Warren的一个链接,我收到了以下警告:
In [1016]: np.linalg.norm(100000*np.ones(2).astype('int16'))
/usr/local/lib/python2.7/site-packages/numpy/linalg/linalg.py:2051: RuntimeWarning: invalid value encountered in sqrt
return sqrt(add.reduce((x.conj() * x).real, axis=None))
对于这个x2
,内部表达式是负数——这是小数据类型溢出的结果
In [1040]: x2=100000*np.ones(2).astype('int16')
In [1041]: np.add.reduce((x2.conj()*x2).real,axis=None)
Out[1041]: -1474836480
类似地,对于x1
:
In [1042]: x1
Out[1042]: array([ -9100, -11900, -13700, -13200], dtype=int16)
In [1043]: np.add.reduce((x1.conj()*x1).real,axis=None)
Out[1043]: -66128
如果“点”的总和对于dtype
来说太大,它可能是负数,在通过sqrt
时产生nan
(我在linux下使用1.8.2和1.9.0)