2016-01-21 73 views
-1

什麼是最快的方法來刪除numpy數組中的元素,同時檢索其初始位置。以下代碼不會返回它應該顯示的所有元素:用迭代從numpy數組中刪除元素

list = [] 
for pos,i in enumerate(ARRAY): 
    if i < some_condition: 
     list.append(pos) #This is where the loop fails 

for _ in list: 
    ARRAY = np.delete(ARRAY, _) 
+0

它失敗了,因爲'p'應該是'pos' –

+0

對不起,這裏寫錯了,現在寫成正確 – KeVal

+0

爲什麼你這麼肯定那條線是你的失敗所在? – user2357112

回答

2

真的覺得您正在低效地進行此操作。您應該可以使用更多的內置numpy功能 - 例如np.where或布爾索引。在這樣的循環中使用np.delete打算殺死任何性能提升您使用numpy的獲得......

例如(布爾索引):

keep = np.ones(ARRAY.shape, dtype=bool) 
for pos, val in enumerate(ARRAY): 
    if val < some_condition: 
     keep[pos] = False 
ARRAY = ARRAY[keep] 

當然,這也可能會被簡化(和廣義)更進一步:

ARRAY = ARRAY[ARRAY >= some_condition] 

編輯

您在COM已經說明意味着你需要相同的掩碼來操作其他陣列 - 這不是問題。你可以保持一個手柄上的面具和用於其他數組:

mask = ARRAY >= some_condition 
ARRAY = ARRAY[mask] 
OTHER_ARRAY = OTHER_ARRAY[mask] 
... 

而且(也許這是你原來的代碼是不工作的原因),只要您刪除第一個指數從循環中的數組中,所有其他項都將一個索引向左移動,所以實際上並沒有刪除在初始傳遞中「標記」的相同項。

作爲一個例子,可以說,你的原始數組是[a, b, c, d, e]和原來的傳球,你在標記爲刪除(ac)指標[0, 2]元素......在第一次通過你刪除循環,你會在索引0刪除項目 - 這將使你的數組​​:

[b, c, d, e] 

現在您刪除循環的第二次迭代,你會在索引2 新數組中刪除的項目:

[b, c, e] 

但看看,而不是像我們想要去除c,我們實際上刪除d!哦,快點!

爲了解決這個問題,你可能會在reversed(list)上編寫你的循環,但是這仍然不會導致快速操作。

+0

我正在考慮使用while循環,但它不會返回錯誤元素的位置。我需要位置,因爲其他一些數組也需要在這些特定位置刪除元素(所以稍後可以繪製圖形)。 – KeVal

+0

@KeVal - 這不是問題。只需在面罩上保留一個手柄並將其用於其他陣列。 (請參閱我的編輯)。 – mgilson

2

你不需要迭代,特別是用這樣的簡單條件。而你並不真的需要使用delete

樣品陣列:

In [693]: x=np.arange(10) 

面具,布爾數組是一個條件爲真(假):

In [694]: msk = x%2==0 
In [695]: msk 
Out[695]: array([ True, False, True, False, True, False, True, False, True, False], dtype=bool) 

where(或nonzero)將其轉換爲索引

In [696]: ind=np.where(msk) 
In [697]: ind 
Out[697]: (array([0, 2, 4, 6, 8], dtype=int32),) 

您使用整體在一個呼叫inddelete(不需要重複):

In [698]: np.delete(x,ind) 
Out[698]: array([1, 3, 5, 7, 9]) 

你可以用它ind保留這些值來代替:

In [699]: x[ind] 
Out[699]: array([0, 2, 4, 6, 8]) 

或者你也可以直接使用布爾msk

In [700]: x[msk] 
Out[700]: array([0, 2, 4, 6, 8]) 

或使用其反轉:

In [701]: x[~msk] 
Out[701]: array([1, 3, 5, 7, 9]) 

delete不會做比這種布爾掩碼更多的東西。這是所有的Python代碼,所以你可以很容易地研究它。