Python 当对具有无限值的矩阵调用时,Numpy triu生成nan

Python 当对具有无限值的矩阵调用时,Numpy triu生成nan,python,numpy,Python,Numpy,刚刚在triu函数的Numpy 1.8.1中发现了一些意外行为 import numpy as np a = np.zeros((4, 4)) a[1:, 2] = np.inf a >>>array([[ 0., 0., 0., 0.], [ inf, 0., 0., 0.], [ inf, 0., 0., 0.], [ inf, 0., 0., 0.]]) np.

刚刚在triu函数的Numpy 1.8.1中发现了一些意外行为

import numpy as np
a = np.zeros((4, 4))
a[1:, 2] = np.inf
a
>>>array([[  0.,   0.,   0.,   0.],
          [ inf,   0.,   0.,   0.],
          [ inf,   0.,   0.,   0.],
          [ inf,   0.,   0.,   0.]])

np.triu(a)
>>>array([[  0.,   0.,   0.,   0.],
          [ nan,   0.,   0.,   0.],
          [ nan,   0.,   0.,   0.],
          [ nan,   0.,   0.,   0.]])
这种行为是否值得追求?或者我应该提交一份bug报告

编辑

我在Numpy github页面上提出了一个问题。解释 看起来您忽略了运行时警告:

>>> np.triu(a)
twodim_base.py:450: RuntimeWarning: invalid value encountered in multiply
  out = multiply((1 - tri(m.shape[0], m.shape[1], k - 1, dtype=m.dtype)), m)
详情如下:

def triu(m, k=0):
    m = asanyarray(m)
    out = multiply((1 - tri(m.shape[0], m.shape[1], k - 1, dtype=m.dtype)), m)
    return out
这用于获得对角线下方为1,上方为0的数组,并将其从1中减去,得到对角线下方为0,上方为1的数组:

>>> 1 - np.tri(4, 4, -1)
array([[ 1.,  1.,  1.,  1.],
       [ 0.,  1.,  1.,  1.],
       [ 0.,  0.,  1.,  1.],
       [ 0.,  0.,  0.,  1.]])
然后将该元素与原始数组相乘。因此,如果原始数组具有
inf
,则结果具有
inf*0
,即NaN

2.变通办法 用于生成下三角形的索引,并将所有这些项设置为零:

>>> a = np.ones((4, 4))
>>> a[1:, 0] = np.inf
>>> a
array([[  1.,   1.,   1.,   1.],
       [ inf,   1.,   1.,   1.],
       [ inf,   1.,   1.,   1.],
       [ inf,   1.,   1.,   1.]])
>>> a[np.tril_indices(4, -1)] = 0
>>> a
array([[ 1.,  1.,  1.,  1.],
       [ 0.,  1.,  1.,  1.],
       [ 0.,  0.,  1.,  1.],
       [ 0.,  0.,  0.,  1.]])

(根据您对
a
的操作,您可能需要在将这些条目归零之前复制一份。)

奇怪-我没有看到警告。我想他们一定被压制住了。好地方。尽管如此,这并不是真正令人满意的行为,对吗?@Gabriel:这是一个错误。我在不久前对代码做了一些修改,以加快它的速度,但整个乘法方法保持不变。我研究了使用布尔索引而不是乘法,这似乎是一个更合理的解决方案,但它使速度降低了约10%,所以它保持不变。这个测试用例为重新考虑这个决定提供了一个很好的理由,不过……至于您的解决方案,它(可能)要快得多:
mask=~np.tri(*a.shape,dtype=bool);a[mask]=0
,但是是的,这似乎是克服此问题的方法。此问题现已解决,但恐怕要到1.10才能正式发布。非常快的工作,谢谢。在那之前,我将使用变通方法。你可能想看看,它非常圆滑,比这个问题的答案中讨论的要快一点
triu(a,k)
只是
np。其中(np.tri(*a.shape,k=k-1,dtype=bool),0,a)
,而
tril(a,k)
np。其中(np.tri(*a.shape,k=k,dtype=bool),arr,0)