从numpy数组中删除一些元素

luc*_*928 6 python 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
Run Code Online (Sandbox Code Playgroud)

输出是:

[0 1 2 3 4 5]
[0 2 4]
Run Code Online (Sandbox Code Playgroud)

如果我们只改变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
Run Code Online (Sandbox Code Playgroud)

错误消息:

IndexError: index 5 is out of bounds for axis 0 with size 5
Run Code Online (Sandbox Code Playgroud)

为什么只有删除最后一个元素才会出现此错误?做这些任务的正确方法是什么?

Gar*_*t R 11

请记住,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) 
Run Code Online (Sandbox Code Playgroud)

解决问题的方法之一是按降序对要删除的索引进行排序(如果您确实要删除该数组).

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

要么:

inds_to_keep = np.array([0,2,4])
values = values[inds_to_keep]
Run Code Online (Sandbox Code Playgroud)


MSe*_*ert 6

一种可能更快的方法(因为您不需要删除每个值而是一次删除所有值)是使用布尔掩码:

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.
Run Code Online (Sandbox Code Playgroud)

建议在 numpy 参考上 np.delete

对于您的问题:您删除一个元素,因此数组变得更短,索引 5 不再在数组中,因为以前的索引 5 现在有索引 4。如果您想使用 np.delete,请按降序删除。

如果您真的想np.delete使用速记删除:

np.delete(values, [3,5,1])
Run Code Online (Sandbox Code Playgroud)

如果要删除值所在的位置(而不是索引),则必须稍微更改程序。如果要删除5数组中的所有值,可以使用:

values[values != 5]
Run Code Online (Sandbox Code Playgroud)

或者有多个要删除的值:

to_delete = (values == 5) | (values == 3)  | (values == 1)
values[~to_delete]
Run Code Online (Sandbox Code Playgroud)

所有这些都为您提供了所需的结果,但不确定您的数据的真实情况,因此我无法确定哪个是最合适的。