2017-06-22 48 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])