簡體   English   中英

在numpy中更新整數索引切片的快速方法

[英]Fast way to update integer indexed slice in numpy

我有一個很大的numpy數組,並且我要清理數據(這是偽代碼):

arr = np.ones(shape=(int(5E5), 1000), dtype=float)
to_zero = np.arange(500, 1000, 2) # Normally this is a function that finds 
                                  # columns be zeroed indexes are not continous
arr[:, to_zero] = 0

問題是arr[:, to_zero] = 0需要很長時間。 在此示例中,此過程需要4秒鍾。 arr[:, :500]需要500毫秒。

有什么辦法可以使速度更快?

numpy 1.8.1numpy 1.9 beta的 numpy筆記本示例(請參閱計時結果)。

正如@Jaime指出的那樣,從長遠來看,使用較新的numpy是一個不錯的選擇。

從numpy的內部存儲角度來看,重置大量連續內存非常快。 以您的示例為例,問題在於您正在將內存調零,就像瘋了的兔子一樣在內存中跳躍。

我嘗試將數組反過來旋轉,然后速度幾乎提高了3倍。對於您的版本,我得到4.08 s,對於換位版本,我得到1.57 s。 因此,如果您可以否則,至少這是一個很好的優化。

此索引在numpy中可能有些麻煩,因為實際上是在做:

for c in to_zero:
    arr[:, c] = 0

比使用列表符號更快。

因此,我運行了幾種不同的選擇:

to_zero = numpy.arange(0, 500, 2)

# 1. table in the original orientation
arr = numpy.ones((500000, 1000), dtype='float')

# 1.1. basic case: 4.08 s
arr[:, to_zero] = 0

# 1.2. a bit different notation: 234 ms 
arr[:, 0:500:2] = 0

# 1.3. for loop: 2.75 s
for c in to_zero:
    arr[:, c] = 0

# 2. transposed table
arr = numpy.ones((1000, 500000), dtype='float')

# 2.1. basic case: 1.47 s
arr[to_zero,:] = 0

# 2.2. a bit different notation: 105 ms 
arr[0:500:2,:] = 0

# 2.3. for loop: 112 ms
for r in to_zero:
    arr[r, :] = 0

這些已使用IPython%timeit進行了計時,因此一次運行到另一次運行的結果可能有所不同,但似乎存在一種模式。 轉置表並使用循環。

問題必須與在內存中分配數據的方式有關。

但是要解決您的問題,請將行讀取為列,將列讀取為行:

arr = np.ones(shape=(1000, int(5E5)), dtype=float)
to_zero = np.arange(500, 1000, 2) # Normally this is a function that finds 
                              # columns be zeroed indexes are not continous
arr[to_zero, :] = 0

暫無
暫無

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

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