2012-12-29 59 views
2

我想從Numpy數組表示的圖像中移除行或列。我的圖像類型是uint16和2560 x 2176.作爲一個例子,說我想刪除前16列,使其2560 x 2160.高效地移除numpy圖像數組的行/列

我是一個MATLAB到Numpy的轉換,並在MATLAB中使用類似:

A = rand(2560, 2196); 
A(:, 1:16) = []; 

據我瞭解,這將刪除列到位,並通過不復制到新陣列節省了大量的時間。

對於Numpy,以前的帖子已經使用過像numpy.delete這樣的命令。但是,文檔很清楚,它會返回一份副本,因此我必須將副本重新分配給A.這似乎會浪費大量時間進行復制。

import numpy as np 

A = np.random.rand(2560,2196) 
A = np.delete(A, np.r_[:16], 1) 

這是否真的和就地刪除一樣快?我覺得我必須錯過一個更好的方法,或者不知道python在刪除期間如何處理數組存儲。

有關以前的帖子:
Removing rows in NumPy efficiently
Documentation for numpy.delete

+1

你有沒有那個「Matlab的刪除列的地方,而不復制數據」這一事實的內容?我找不到任何正式的東西,而且從我讀過的東西中,我必須複製整個數組,這對我來說似乎是合理的。在numpy中,你會使用基本的切片(蒂亞戈的回答)來避免複製。考慮到這意味着整個原始數組仍將存在於內存中,因爲您獲得了一個視圖。 – jorgeca

回答

4

爲什麼不只是做一個切片?在這裏,我除去第一列3000,而不是16,使內存的使用更加清晰:

import numpy as np 
a = np.empty((5000, 5000) 
a = a[:, 3000:] 

這有效地降低了存儲陣列的大小,可以看出:

In [31]: a = np.zeros((5000, 5000), dtype='d') 
In [32]: whos 
Variable Type  Data/Info 
------------------------------- 
a   ndarray 5000x5000: 25000000 elems, type `float64`, 200000000 bytes (190 Mb) 
In [33]: a = a[:, 3000:] 
In [34]: whos 
Variable Type  Data/Info 
------------------------------- 
a   ndarray 5000x2000: 10000000 elems, type `float64`, 80000000 bytes (76 Mb) 

對於這種大小的數組中分得一杯羹似乎是約10,000比你刪除選項更快:

%timeit a=np.empty((5000,5000), dtype='d'); a=np.delete(a, np.r_[:3000], 1) 
1 loops, best of 3: 404 ms per loop 
%timeit a=np.empty((5000,5000), dtype='d'); a=a[:, 3000:] 
10000 loops, best of 3: 39.3 us per loop 
+0

這看起來好多了。 1)你是否知道這是否需要將片段複製到新內存中? 2)刪除本質上比切片慢,還是我使用不當? – nicktruesdale

+1

切片不會將數組複製到新的內存中(與刪除不同)。我認爲,將數組分配給它的一部分也不會將其複製到內存中。在內部,我認爲numpy只是將'a'分配給同一個內存塊中的不同指針。 – tiago

+1

'np.delete'比較慢,並且會始終返回一個副本,但即使在numpy 1.8之前,甚至花哨的索引(或用布爾數組切片)也會更好。 (在多數情況下)。如果一個簡單的slice不夠用,你需要複製(我也確信在matlab中),但是即使這樣,你仍然應該在這個時候通過'np.delete'提供一個索引數組。 – seberg