Numpy选择懒人版

时间:2015-10-20 22:58:59

标签: python numpy select lazy-evaluation

考虑以下代码

 >>> 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。

是否存在一个懒惰且没有上述问题的选择版本?

1 个答案:

答案 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的价值不被评估。辅助数组xfun2lambdax的每个值定义一个虚拟x+1;第一个返回1/x,第二个返回xfun2[2]()。但是,在将元素称为select之前,不会对它们进行评估。

所以我们使用lambda调用从两个函数数组中选择元素,然后我们获得一个函数列表。为了获得数字返回值,我们需要使用列表推导来评估每个You might need to install other software to open this address.