我是Numpy和OpenCV的新手。我发现Numpy数组只能为第一个维度的范围建立索引是很奇怪的:
AtomicReference
使用范围索引将返回长度为3的向量,使用整数索引将返回3x3数组。前者在将值分配给索引数组时抛出错误,后者工作正常。
为什么会这样?
答案 0 :(得分:1)
您使用range
而不是列表这一事实与您的错误无关。
使数组具有独特的值:
In [30]: a = np.arange(9).reshape(3,3)
In [31]: a
Out[31]:
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
索引两个范围会生成一个1d数组,在这种情况下是对角线。
In [32]: a[range(3),range(3)]
Out[32]: array([0, 4, 8])
a[[0,1,2], [0,1,2]]
会做同样的事情。错误中的(3,)块引用此1d数组。
要获得等效于[0:3, 0:3]
切片的块,必须使用相互广播的数组。方便的实用程序是ix_
:
In [33]: np.ix_(range(3), range(3))
Out[33]:
(array([[0],
[1],
[2]]), array([[0, 1, 2]]))
请注意,一个数组是(3,1),另一个数组是(1,3);一起广播时,它们引用了(3,3)个值块:
In [34]: a[np.ix_(range(3), range(3))]
Out[34]:
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
现在我们可以为其分配一个(3,3)值数组:
In [35]: a[np.ix_(range(3), range(3))] = np.ones((3,3))
In [36]: a
Out[36]:
array([[1, 1, 1],
[1, 1, 1],
[1, 1, 1]])
答案 1 :(得分:0)
区别在于,在Python 3.x中,range()生成一个迭代器而不是列表。在Python 2.x之前,xrange()使用了此功能。但是,现在,只需调用range()即可生成迭代器。