2017-06-22 124 views
0

在什么样的具体情况下,np.piecewise会比np.where更方便(不太详细)或计算上比使用np.where更有效吗?我在遇到这种情况时遇到了问题,而且我似乎碰到了经常用where进行评估的分段函数。NumPy分段与NumPy其中

np.piecewise似乎更加详细不论件数:

import numpy as np 
b = np.arange(10, 20, dtype=np.float) 

# 2 pieces - piecewise is more verbose 
a = np.piecewise(b, [b<14, b>=14], [lambda x: x**2, lambda x: x/2]) 
c = np.where(b>=14, b/2, b ** 2) 
print(np.array_equal(a, c)) 
True 

# 3 pieces - piecewise still more verbose (won't it always be?) 
d = np.piecewise(b, [b<11, np.logical_and(b>=11, b<14), b>=14], 
       [1, lambda x: x**2, lambda x: x/2]) 
e = np.where(b>=14, b/2, np.where(b>=11, b**2, 1)) 
print(np.array_equal(d, e)) 
True 

这也是显著慢:

from timeit import timer 
# variables above redefined as callables with no args 
print('times:\n a: %d, c: %d, d: %d, e: %d' 
     % (timeit(a), timeit(c), timeit(d), timeit(e))) 
times: 
a: 17, c: 4, d: 21, e: 7 

回答

1

在情况下,它可以帮助你确定,这里就是piecewise做:

In [2]: b = np.arange(10,20,dtype=float) 

定义2名输入名单;注意现在条件(s)被评估。

In [12]: condlist = [b<14, b>=14] 
In [13]: condlist 
Out[13]: 
[array([ True, True, True, True, False, False, False, False, False, False], dtype=bool), 
array([False, False, False, False, True, True, True, True, True, True], dtype=bool)] 
In [14]: fnlist = [lambda x: x**2, lambda x: x/2] 

piecewise只是在2所列出迭代,并且将值分配给目标阵列:

In [15]: a = np.zeros_like(b) 
In [16]: for k in range(len(condlist)): 
    ...:  idx = condlist[k] 
    ...:  a[idx] = fnlist[k](b[idx]) 
    ...:  
In [17]: a 
Out[17]: 
array([ 100. , 121. , 144. , 169. , 7. , 7.5, 8. , 8.5, 
      9. , 9.5]) 

In [18]: np.piecewise(b, condlist, fnlist) 
Out[18]: 
array([ 100. , 121. , 144. , 169. , 7. , 7.5, 8. , 8.5, 
      9. , 9.5]) 

这对where是相似的,除了所述的fnlist呼叫被施加到整个的b而比一个子集。在这样简单的计算中,它可能没有太大的区别。

In [21]: a = np.where(condlist[0], fnlist[0](b),0) 
In [22]: a = np.where(condlist[1], fnlist[1](b),a) 
In [23]: a 
Out[23]: 
array([ 100. , 121. , 144. , 169. , 7. , 7.5, 8. , 8.5, 
      9. , 9.5]) 

在某些情况下,这是错误的整个范围b值来评估一个功能 - 如果涉及除以0分段的选择性评估会更好,例如。

冗长度不应该是一个重要的措施。我们已经花了更多时间输入问题和答案。在工作代码中,罗嗦的代码可以隐藏在函数中。从长远来看,可读性更重要。

1

piecewise比较快,如果计算是缓慢的,因为只有值,需要计算。

较短的版本:

d = np.piecewise(b, [b<11, (b>=11)&(b<14)], [1, lambda x: x**2, lambda x: x/2])