简体   繁体   English

如何修复python中的“index is of bounds”错误,使用numpy?

[英]How to fix “index is out of bounds” error in python, working with numpy?

I'm trying to build a function that removes any negative numbers out of an array, but gets a error message. 我正在尝试构建一个从数组中删除任何负数的函数,但会收到错误消息。 What do I need to change? 我需要改变什么?

This is for python 3 using the numpy library The code I've tried so far is: 这是使用numpy库的python 3我到目前为止尝试的代码是:

def drop_negative_numbers(a):
    b = a
    for i in range(a.size): 
        if a[i] < 0:
            b = np.delete(b, a[i])       
    return b

I'm trying to make this assert work: 我试图使这个断言工作:

a = np.array([1, 2, -3, 4, -5])
b = drop_negative_numbers(a)
npt.assert_equal(b, [1, 2, 4])

But i get this error message: IndexError: index -5 is out of bounds for axis 0 with size 4 但我收到此错误消息:IndexError:索引-5超出轴0的大小为4

The mistake is in the assignment b = a . 错误在于作业b = a b is then not a copy, just a(nother) view into a : any chances in b are reflected in a . b然后不是副本,只是a(另一个)视图ab中的任何机会都反映在a If you use b = a.copy() (or b = a[:] ) in your function, your code will work. 如果在函数中使用b = a.copy() (或b = a[:] ),则代码将起作用。

With NumPy, however, it's clearer and faster to think vector(array)-wise: use, for example, 然而,使用NumPy,思考向量(数组)方向更清晰,更快:例如,使用

a = np.array([1, 2, -3, 4, -5])
b = a[a >= 0]

and you don't need your function anymore. 而且你不再需要你的功能了。

In your for loop you iterate over the array a number of times, if you then remove -3, you only have 4 items in the array. 在for循环中,您多次遍历数组,如果删除-3,则数组中只有4个项目。 You then get to -5 and you try to remove that item, but that would be item 5 (4, when you start on 0) which means that your index is invalid as there isn't an item 5 in your array any more. 然后你到-5并且你试图删除那个项目,但那将是项目5(4,当你从0开始)这意味着你的索引无效,因为你的数组中没有项目5了。

You want to make a copy of the array at the start, then iterate over one list and remove from another 您希望在开始时创建数组的副本,然后迭代一个列表并从另一个列表中删除

Look in detail at what happens with each delete: 详细了解每次删除会发生什么:

In [43]: a                                                                      
Out[43]: array([ 1,  2, -3,  4, -5])
In [44]: b=a                                                                    
In [45]: a[2]                                                                   
Out[45]: -3
In [46]: b=np.delete(b, a[2])                                                   
In [47]: b                                                                      
Out[47]: array([ 1,  2,  4, -5])
In [48]: a[4]                                                                   
Out[48]: -5
In [49]: b=np.delete(b, a[4])                                                   
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-49-a326bbe5d5c9> in <module>
----> 1 b=np.delete(b, a[4])

/usr/local/lib/python3.6/dist-packages/numpy/lib/function_base.py in delete(arr, obj, axis)
   4374             raise IndexError(
   4375                 "index %i is out of bounds for axis %i with "
-> 4376                 "size %i" % (obj, axis, N))
   4377         if (obj < 0):
   4378             obj += N

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

delete makes a new array each time. delete每次都会创建一个新数组。 That makes it slower than similar list methods. 这使得它比类似的列表方法慢。 But it does mean that a does not get changed. 但这确实意味着a不会改变。

np.delete takes an index, not a value (it's not the same as the list del ). np.delete接受一个索引,而不是一个值(它与list del )。 a[2] just happens to work because a[-3] is [-3] . a[2]恰好起作用,因为a[-3][-3] a[4] is -5 which isn't a valid index in the size 4 b . a[4]-5 ,它不是大小b的有效索引。

If we specify the index rather than value, the deletes work correctly: 如果我们指定索引而不是值,则删除工作正常:

In [51]: b=a                                                                    
In [52]: b=np.delete(b, 2)                                                      
In [53]: b                                                                      
Out[53]: array([ 1,  2,  4, -5])
In [54]: b=np.delete(b, 3)                                                      
In [55]: b                                                                      
Out[55]: array([1, 2, 4])

But a repeated delete is slow; 但重复delete很慢; better to delete all negative numbers at once: 最好一次删除所有负数:

In [56]: a                                                                      
Out[56]: array([ 1,  2, -3,  4, -5])
In [57]: np.delete(a,[2,4])                                                     
Out[57]: array([1, 2, 4])

We can use where to get the indices: 我们可以使用where来获取索引:

In [65]: a<0                                                                    
Out[65]: array([False, False,  True, False,  True])
In [66]: np.where(a<0)                                                          
Out[66]: (array([2, 4]),)
In [67]: np.delete(a, np.where(a<0))                                            
Out[67]: array([1, 2, 4])

But we can use the mask directly: 但是我们可以直接使用面具:

In [68]: a[~(a<0)]                                                              
Out[68]: array([1, 2, 4])

for a list, a simple list comprehension works nicely: 对于列表,一个简单的列表理解很好地工作:

In [69]: b = a.tolist()                                                         
In [70]: [i for i in b if not i<0]                                              
Out[70]: [1, 2, 4]

Another well known trick with lists, is to iterate from the end, so that any deletions won't mess up the remaining list. 列表的另一个众所周知的技巧是从最后进行迭代,这样任何删除都不会弄乱剩余的列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM