Skip to main content
 首页 » 编程设计

python之使用 if 语句优化作用于 numpy 数组的函数

2025年05月04日12rubylouvre

假设我有这样的代码:

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 有一点时间优势。)