2016-02-27 656 views
4

一個有趣的問題:刪除numpy的陣列的一些元素

我想刪除從numpy的陣列的一些元素,但正如下面的簡化示例代碼,如果沒有刪除最後一個元素,它的工作原理,但它失敗如果我們想刪除最後一個元素。 下面的代碼工作正常:

import numpy as np 

values = np.array([0,1,2,3,4,5]) 
print values 
for i in [3,4,1]: 
    values = np.delete(values,i) 
print values 

輸出是:

[0 1 2 3 4 5] 
[0 2 4] 

如果只改變4到5,然後它會失敗:

import numpy as np 

values = np.array([0,1,2,3,4,5]) 
print values 
for i in [3,5,1]: 
    values = np.delete(values,i) 
print values 

錯誤消息:

IndexError: index 5 is out of bounds for axis 0 with size 5 

爲什麼選擇th僅當刪除最後一個元素時纔會發生錯誤?做這些任務的正確方法是什麼?

+0

想要刪除索引''[3,4,1]''或值''[3,4,1 ]''?這很令人困惑,因爲數組中的值與索引相同 – gsmafra

回答

7

請記住,np.delete(arr,ind)會刪除索引爲ind的元素,而不是具有該值的元素。

這意味着當你刪除東西時,數組越來越短。所以,你有

values = [0,1,2,3,4,5] 
np.delete(values, 3) 
[0,1,2,4,5] #deleted element 3 so now only 5 elements in the list 
#tries to delete the element at the fifth index but the array indices only go from 0-4 
np.delete(values, 5) 

一個可以解決問題的方法是開始要在降序(如果你真的要刪除陣列)刪除索引排序。

inds_to_delete = sorted([3,1,5], reverse=True) # [5,3,1] 
# then delete in order of largest to smallest ind 

或者:

inds_to_keep = np.array([0,2,4]) 
values = values[inds_to_keep] 
2

的問題是,你從values所以當你試圖刪除索引5項目有該索引處不再值刪除的項目,它現在是在指數4

如果對要刪除的索引列表進行排序,並將它們從大到小迭代,應該解決此問題。

import numpy as np 

values = np.array([0,1,2,3,4,5]) 
print values 
for i in [5,3,1]: # iterate in order 
    values = np.delete(values,i) 
print values 
3

一個可能更快捷的方式(因爲你並不需要刪除的每一個值,但一次全部)使用布爾面膜:

values = np.array([0,1,2,3,4,5]) 
tobedeleted = np.array([False, True, False, True, False, True]) 
# So index 3, 5 and 1 are True so they will be deleted. 
values_deleted = values[~tobedeleted] 
#that just gives you what you want. 

建議上np.delete的numpy的參考

你的問題:刪除一個元素,使得數組變得更短,並且索引5不再位於數組中,因爲前面的索引5現在具有索引4.如果要使用np.delete,則按降序刪除。如果要刪除其中的值(而不是索引),你必須改變的過程有點

np.delete(values, [3,5,1]) 

如果你真的要刪除與np.delete使用簡寫。如果你想刪除陣列中的所有值5你可以使用:

values[values != 5] 

或多個值刪除:

to_delete = (values == 5) | (values == 3) | (values == 1) 
values[~to_delete] 

所有這些給你想要的結果,不知道如何您的數據看起來確實如此,所以我無法確定哪一種最合適。

2

如果你想刪除指數3,4,1的元素,只是做np.delete(values,[3,4,1])

如果您希望在第一種情況下刪除第四個(index = 3)項目,那麼剩下的第五個和其餘的第二個,由於操作的順序,您刪除第二個,第四個和最初陣列的第六個。因此,第二種情況是失敗的邏輯。

你可以計算這樣的轉變(在第五屆爲例成爲第六位):

def multidelete(values,todelete): 
    todelete=np.array(todelete) 
    shift=np.triu((todelete>=todelete[:,None]),1).sum(0) 
    return np.delete(values,todelete+shift) 

一些測試:

In [91]: multidelete([0, 1, 2, 3, 4, 5],[3,4,1]) 
Out[91]: array([0, 2, 4]) 

In [92]: multidelete([0, 1, 2, 3, 4, 5],[1,1,1]) 
Out[92]: array([0, 4, 5]) 

注: np.delete不抱怨如果不良指標在列表中,則什麼也不做:np.delete(values,[8])values

0

布爾指數被刪除。你可以像這樣使用函數np.where():

values = np.array([0,1,2,3,4,5]) 
print(values) 
for i in [3,5,1]: 
    values = np.delete(values,np.where(values==i)) 
    # values = np.delete(values,values==i) # still works with warning 
print(values)