我试图在多维数组上使用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]])
答案 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
在减少投票人数之前,这显然不是最佳实践,并且可能会因您的使用情况而产生副作用,但我以为我会在那里提出替代方案。