考虑以下代码
>>> x = np.array([0, 0, 1, 1])
>>> np.select([x==0, True], [x+1, 1/x])
array([ 1., 1., 1., 1.])
它有两个问题。
首先,它不是懒惰的。它急切地评估x + 1和1 / x,即使最终结果中不需要某些评估值。
其次,numpy每次运行代码时都会发出警告
RuntimeWarning: divide by zero encountered in true_divide
与前一点有些相关,因为即使在最终答案中不需要,也会尝试评估1 / x。
是否存在一个懒惰且没有上述问题的选择版本?
答案 0 :(得分:3)
您可以通过在两种情况下显式屏蔽输出向量来避免评估:
y=x[:]
mask= x==0
y[mask]=x[mask]+1
y[~mask]=1/x[~mask]
<强>更新强>
我终于可以实现实际的懒惰评估,虽然它有点凌乱并且造成了不必要的复杂情况(好吧,至少在这种情况下;我可以想象有些情况下这可能会派上用场)。本着#34的精神,任何值得做的事都值得过度使用&#34;:
xfun1=[lambda xx=xx:xx+1 for xx in x]
xfun2=[lambda xx=xx:1/xx for xx in x]
[fun() for fun in np.select([x==0, True], [xfun1,xfun2])]
我们的想法是通过将1/x
定义隐藏在lambda
后面来保护xfun1
的价值不被评估。辅助数组xfun2
和lambda
为x
的每个值定义一个虚拟x+1
;第一个返回1/x
,第二个返回xfun2[2]()
。但是,在将元素称为select
之前,不会对它们进行评估。
所以我们使用lambda
调用从两个函数数组中选择元素,然后我们获得一个函数列表。为了获得数字返回值,我们需要使用列表推导来评估每个You might need to install other software to open this address.
。