我正在尝试构建一个函数,该函数将从数组中删除所有负数,但会收到错误消息。我需要更改什么?
这是使用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
我正在尝试使该断言起作用:
a = np.array([1, 2, -3, 4, -5])
b = drop_negative_numbers(a)
npt.assert_equal(b, [1, 2, 4])
但是我收到此错误消息:IndexError:索引-5超出了轴4尺寸4的范围
答案 0 :(得分:0)
错误出在分配b = a
中。 b
不是副本,而只是a
的(另一种)视图:b
中的任何机会都将反映在a
中。如果您在函数中使用b = a.copy()
(或b = a[:]
),则代码将起作用。
但是,使用NumPy,更明智地思考矢量(数组)方式:例如,使用
a = np.array([1, 2, -3, 4, -5])
b = a[a >= 0]
您不再需要功能。
答案 1 :(得分:0)
在for循环中,您需要多次遍历数组,如果再删除-3,则数组中只有4个项目。然后,您进入-5并尝试删除该项目,但这将是项目5(从0开始时为4),这意味着您的索引无效,因为数组中不再有项目5。
您想在开始时复制数组,然后遍历一个列表,然后从另一个列表中删除
答案 2 :(得分:0)
详细查看每次删除会发生什么情况
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
每次都会创建一个新数组。这使其比类似的列表方法慢。但这确实意味着a
不会被更改。
np.delete
接受索引,而不是值(与列表del
不同)。 a[2]
恰好起作用,因为a[-3]
是[-3]
。 a[4]
是-5
,它不是大小为4 b
的有效索引。
如果我们指定索引而不是值,则删除工作正常:
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])
但是重复的delete
很慢;最好一次删除所有负数:
In [56]: a
Out[56]: array([ 1, 2, -3, 4, -5])
In [57]: np.delete(a,[2,4])
Out[57]: array([1, 2, 4])
我们可以使用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])
但是我们可以直接使用蒙版:
In [68]: a[~(a<0)]
Out[68]: array([1, 2, 4])
对于列表,一个简单的列表理解就可以很好地工作:
In [69]: b = a.tolist()
In [70]: [i for i in b if not i<0]
Out[70]: [1, 2, 4]
列表的另一个众所周知的技巧是从末尾进行迭代,以使任何删除都不会弄乱其余列表。