簡體   English   中英

在 cython 中修剪 numpy 陣列

[英]Trimming a numpy array in cython

目前,我有以下 cython function,修改 numpy 數組的條目,其中填充零以求和非零值。 在我返回數組之前,我想修剪它並刪除所有非零條目。 目前,我使用 numpy function myarray = myarray[~np.all(myarray == 0, axis=1)]這樣做。 我想知道(通常)是否有更快的方法來使用 Cython/C function 而不是依賴 python/numpy。 這是我的腳本中 Pythonic 交互的最后一點之一(使用 to %%cython -a檢查)。 但我真的不知道如何處理這個問題。 一般來說,我不知道最終數組中非零元素的數量。

cdef func():
   np.ndarray[np.float64_t, ndim=2] myarray = np.zeros((lenpropen, 6)) 
   """
   computations
   """

   myarray = myarray[~np.all(myarray == 0, axis=1)]
   return myarray

如果最高維度始終包含少量元素,例如 6,那么您的代碼不是最好的。

首先, myarray == 0np.all~創建臨時的 arrays引入一些額外的開銷,因為它們需要被寫入和讀回。 開銷取決於臨時數組的 this ,最大的是myarray == 0

此外,Numpy 調用會執行一些 Cython 無法刪除的不需要的檢查 這些檢查引入了恆定的時間開銷。 因此,對於小輸入 arrays 但不是大輸入 arrays 可能相當大。

此外,如果np.all的代碼知道最后一個維度的確切大小(此處不是這種情況),它會更快。 實際上, np.all的循環理論上可以展開,因為最后一個維度很小。 不幸的是, Cython 沒有優化 Numpy 調用,並且 Numpy 是針對可變輸入大小編譯的,因此在編譯時不知道

最后,如果lenpropen很大,計算可以並行化(否則這不會更快,實際上可能更慢)。 但是,請注意,並行實現需要分兩步完成計算: np.all(myarray == 0, axis=1)需要並行計算,然后您可以創建結果數組並通過計算myarray[~result]來編寫它myarray[~result]並行。 按順序,您可以通過就地過濾線直接覆蓋myarray ,然后生成過濾線的視圖。 這種模式被稱為erase-remove idiom 請注意,這假設數組是連續的

總而言之,更快的實現包括編寫 2 個在myarray上迭代的嵌套循環,其中最內層的迭代次數恆定。 關於lenpropen的大小,您可以使用基於擦除刪除習慣用法的順序就地實現,也可以使用具有兩個步驟(和一個臨時數組)的並行就地實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM