2016-11-30 30 views
1

我有一個numpy函數,它將x,y座標的二維數組轉換爲前一個之間每個座標距離的平面數組。 (見Numpy - transform 2D array of x,y coordinates into flat array of distance between coordinatesNumpy - 將一個numpy函數轉換爲發生器

input = [[-8081441,5685214], [-8081446,5685216], [-8081442,5685219], [-8081440,5685211], [-8081441,5685214]] 
output = [-8081441, 5685214, 5, -2, -4, -3, -2, 8, 1, -3] 

感謝Divakar's answer,我有一個做我想

arr = np.asarray(input).astype(int) 
np.hstack((arr[0], (-np.diff(arr, axis=0)).ravel())) 

與切片的另一種方法來複制分化2個numpy的功能 -

arr = np.asarray(input).astype(int) 
np.hstack((arr[0], (arr[:-1,:] - arr[1:,:]).ravel())) 

我的問題是,是否有辦法將這些numpy函數之一轉換爲生成器以提高性能?是否可以在生成器中使用numpy?

+2

首先,謹防過早優化的,你有你想要做什麼的功能。其次,發電機真的不會在這裏幫助你。 Numpy函數從矢量化中獲得了它們的大部分速度,這需要密集的表示,並且基本上對數組中的所有元素進行操作。 – Erotemic

回答

2

Python生成器是列表的衍生物。

In [207]: [i*2 for i in range(3)] 
Out[207]: [0, 2, 4] 
In [208]: (i*2 for i in range(3)) 
Out[208]: <generator object <genexpr> at 0xb6a1ffbc> 
In [209]: list(_) 
Out[209]: [0, 2, 4] 

您可以將其視爲懶惰列表。它不會實際評估元素,直到您遍歷它爲止。在Py3中range是一個生成器(Py2中的xrange)。 In[208]行設置了一個生成器,但不評估任何內容。所以速度很快。但是在[209]中迭代它與[207]中的原始版本一樣長。 (那麼可能會有細微的差別。)

因此,一個生成器可以讓你用列表思考塊,而不用創建所有的中間列表。它更像是一種代碼組織工具,而不是性能。

使用numpy數組時,我想不出任何等價物。

arr=np.array(input) # creates fixed size array from input list 
-np.diff(arr, axis=0) # create another array 

這產生多箇中間陣列,甚至一個列表,並最終返回一個數組(並丟棄中間體):

np.hstack((arr[0],(-np.diff(arr, axis=0)).ravel())) 

有許多在該表達式簡單積木。 Numpy的速度來自在快速編譯代碼中執行這些步驟。爲了獲得更好的速度,你必須用C或者Cython重寫這個問題。在該代碼中,您可以迭代,並在每個步驟執行復雜的操作。

可以想象,numpy可以執行某種懶惰評估,但這需要主要的低級編碼。並且不能保證它會導致性能改進。

我看着中間緩衝區的問題,add.at改進的性能(事實並非如此),在是否:https://stackoverflow.com/a/40688879/901925

+0

謝謝你的回答。最後,性能最高的函數是在生成器中使用迭代器(請參閱[本答案](http://codereview.stackexchange.com/a/147908/68343))。上面的Numpy函數在處理多個大型座標數組時顯着較慢。 –