[英]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(另一个)视图a
: b
中的任何机会都反映在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.