2016-02-27 64 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)