假设0 *无穷大= 0时,如何在NumPy中multiply.outer()?

时间:2016-12-10 00:12:07

标签: python numpy floating-point infinity

我试图在多维数组上使用numpy.multiply.outer,我真的需要它假设它看到的任何0 * infinity计算结果为零。我怎样才能有效地做到这一点?

>>> import numpy
>>> numpy.multiply.outer([0.], [float('inf')])
Warning (from warnings module):
  File "__main__", line 2
RuntimeWarning: invalid value encountered in multiply
array([[ nan]])

4 个答案:

答案 0 :(得分:3)

您是否需要担心nan值的其他来源?如果没有,您可以随时解决这个问题:

import numpy as np

r = np.multiply.outer([0.], [float('inf')])
np.where(np.isnan(r), 0, r)

如果您想要取消警告,请由您决定。

答案 1 :(得分:2)

一种解决方案可能是避免使用np.multiply.outer并在矩阵上使用逐元素乘法找到解决方案,这些矩阵已经过检查以确定它们是否满足感兴趣的条件(在一个数组中为零,{{1}在其他数组中)。

inf

然而,这可能无法通过海报的“效率”要求。

答案 2 :(得分:1)

以下是禁止警告的方法:

mean, nanmean and warning: Mean of empty slice

In [528]: import warnings

In [530]: x = np.array([0,1,2],float)
In [531]: y = np.array([np.inf,3,2],float)
In [532]: np.outer(x,y)
/usr/local/lib/python3.5/dist-packages/numpy/core/numeric.py:1093: RuntimeWarning: invalid value encountered in multiply
  return multiply(a.ravel()[:, newaxis], b.ravel()[newaxis,:], out)
Out[532]: 
array([[ nan,   0.,   0.],
       [ inf,   3.,   2.],
       [ inf,   6.,   4.]])

In [535]: with warnings.catch_warnings():
     ...:     warnings.simplefilter('ignore',category=RuntimeWarning)
     ...:     z = np.outer(x,y)
     ...:     
In [536]: z
Out[536]: 
array([[ nan,   0.,   0.],
       [ inf,   3.,   2.],
       [ inf,   6.,   4.]])

nan替换为1

In [542]: z[np.isnan(z)]=1
In [543]: z
Out[543]: 
array([[  1.,   0.,   0.],
       [ inf,   3.,   2.],
       [ inf,   6.,   4.]])

In [547]: z[np.isinf(z)]=9999
In [548]: z
Out[548]: 
array([[  1.00000000e+00,   0.00000000e+00,   0.00000000e+00],
       [  9.99900000e+03,   3.00000000e+00,   2.00000000e+00],
       [  9.99900000e+03,   6.00000000e+00,   4.00000000e+00]])

=================

我们可以使用mask演示的那种测试来创建@P-robot

In [570]: np.outer(np.isinf(x),y==0)|np.outer(x==0,np.isinf(y))
Out[570]: 
array([[ True, False, False],
       [False, False, False],
       [False, False, False]], dtype=bool)
In [571]: mask=np.outer(np.isinf(x),y==0)|np.outer(x==0,np.isinf(y))
In [572]: with warnings.catch_warnings():
     ...:     warnings.simplefilter('ignore',category=RuntimeWarning)
     ...:     z = np.outer(x,y)
     ...:     
In [573]: z[mask]=1
In [574]: z
Out[574]: 
array([[  1.,   0.,   0.],
       [ inf,   3.,   2.],
       [ inf,   6.,   4.]])

或者使用更混乱的输入:

In [587]: x = np.array([0,1,2,np.inf],float)
In [588]: y = np.array([np.inf,3,np.nan,0],float)
In [589]: mask=np.outer(np.isinf(x),y==0)|np.outer(x==0,np.isinf(y))
...
In [591]: with warnings.catch_warnings():
     ...:     warnings.simplefilter('ignore',category=RuntimeWarning)
     ...:     z = np.outer(x,y)
     ...:     
In [592]: z[mask]=1
In [593]: z
Out[593]: 
array([[  1.,   0.,  nan,   0.],
       [ inf,   3.,  nan,   0.],
       [ inf,   6.,  nan,   0.],
       [ inf,  inf,  nan,   1.]])

答案 3 :(得分:0)

虽然我同意@ShadowRanger的回答,但便宜的破解方法可能是利用np.nan_to_num的优势,它用大数量的有限数替换了infs,这将使您获得inf * 0 = 0。

要将多余的剩余高有限数转换回inf(考虑到问题之外的其他操作),可以将高数乘以> 1,然后除以相同的数量(以免影响其他数)。例如:

In [1]: np.nan_to_num(np.inf)
Out[1]: 1.7976931348623157e+308

In [2]: np.nan_to_num(np.inf)*1.1
RuntimeWarning: overflow encountered in double_scalars
Out[2]: inf

In [3]: np.nan_to_num(np.inf)*1.1/1.1
RuntimeWarning: overflow encountered in double_scalars
Out[3]: inf

在减少投票人数之前,这显然不是最佳实践,并且可能会因您的使用情况而产生副作用,但我以为我会在那里提出替代方案。