假设我有这样的代码:
import numpy as np
def value_error(x):
if x > 10:
return 0.
else:
return np.sin(x)
这可能会给我一个 ValueError:具有多个元素的数组的真值不明确。如果在 numpy 数组上调用,请使用 a.any() 或 a.all()。
现在我可以改为这样做:
def alright(x):
return np.sin(x) * (x <= 10.)
print alright(np.ones(100) * 100)
print value_error(np.ones(100) * 10)
我的函数(在本例中为 np.sin)可能是一个昂贵的函数。但是,它会针对 x 的每个元素调用,即使是因为 x > 10 而我知道答案的那些元素,而无需昂贵的调用。我怎样才能两全其美?
请您参考如下方法:
许多 ufunc 都带有一个 where 参数
In [98]: x=np.arange(10)*2
In [99]: mask = x<10
In [100]: y = np.zeros(10)
In [101]: np.sin(x,where=mask,out=y)
Out[101]:
array([ 0. , 0.90929743, -0.7568025 , -0.2794155 , 0.98935825,
0. , 0. , 0. , 0. , 0. ])
虽然这是一个小案例,timeit 表明它与 mask 使用`@divakar 的答案相比没有太大优势:
In [104]: timeit np.sin(x,where=mask,out=y)
5.17 µs ± 12.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [105]: timeit y[mask] = np.sin(x[mask])
4.69 µs ± 9.54 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
(对于更大的 x,where 参数比使用 mask 有一点时间优势。)
