假设我有一个代码:
import numpy as np
def value_error(x):
if x > 10:
return 0.
else:
return np.sin(x)
如果调用numpy数组,这可能会给我一个ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or 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
,没有昂贵的电话。我如何才能充分利用这两个世界?
答案 0 :(得分:4)
许多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
表明它没有比使用@ {divakar的答案mask
更有优势:
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
使用相比具有轻微的时间优势。)
答案 1 :(得分:2)
请注意,您的函数不会利用numpy的矢量化。有几种可能的选择。
选项1
这似乎是np.where
-
y = np.where(x > 10, 0, np.sin(x))
根据提供的掩码返回值。这是一个样本 -
x
array([ 0.1, 0.2, 0.3, 11. , 0.1, 11. ])
np.where(x > 10, 0, np.sin(x))
array([ 0.09983342, 0.19866933, 0.29552021, 0. , 0.09983342, 0. ])
请注意,此方法仍会为每个元素调用“昂贵的函数”。
选项2
另一种可能性是使用掩码并有条件地设置值 -
y = np.sin(x)
y[x > 10] = 0
与上述类似,您可以将x
乘以掩码并在结果上调用np.sin
-
y = np.sin(x * (x < 10))
正如Divakar所提到的,你可以在这种情况下使用numexpr -
import numexpr as ne
y = ne.evaluate("sin(x * (x < 10))")
这应该比上面的更快。
答案 2 :(得分:2)
这是一个基于掩码的掩码,只对有效的@shared_task
def get_report(name):
sleep(30)
@shared_task
def set_task_status(id):
instance = Scorecard.objects.get(task_id=id)
task_status = AsyncResult(id)
instance.status = task_status.status
instance.save()
进行操作 -
np.sin
利用numexpr
module加快out = np.zeros(x.shape)
mask = x <= 10
out[mask] = np.sin(x[mask])
次操作 -
transcendental