Python 使用range()索引Numpy数组会引发形状不匹配错误

Python 使用range()索引Numpy数组会引发形状不匹配错误,python,arrays,numpy,Python,Arrays,Numpy,我是Numpy和OpenCV的新手。我觉得奇怪的是,Numpy数组只能在第一个维度上使用范围进行索引: 导入numpy >>> >>>a=numpy.zeros((3,3),dtype=numpy.int8) >>> >>>i_范围=范围(3) >>>j_范围=范围(3) >>> >>>打印(i_范围) 范围(0,3) >>>打印(j_范围) 范围(0,3) >>>打印(a[i_范围,j_范围]) [0 0 0] >>>打印(a[0:3,0:3]) [[0 0 0] [0 0 0] [0

我是Numpy和OpenCV的新手。我觉得奇怪的是,Numpy数组只能在第一个维度上使用范围进行索引:

导入numpy >>> >>>a=numpy.zeros((3,3),dtype=numpy.int8) >>> >>>i_范围=范围(3) >>>j_范围=范围(3) >>> >>>打印(i_范围) 范围(0,3) >>>打印(j_范围) 范围(0,3) >>>打印(a[i_范围,j_范围]) [0 0 0] >>>打印(a[0:3,0:3]) [[0 0 0] [0 0 0] [0 0 0]] >>>a[i_range,j_range]=numpy.ones((3,3),dtype=numpy.int8) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 ValueError:形状不匹配:形状(3,3)的值数组无法广播到形状(3,)的索引结果 >>>a[0:3,0:3]=numpy.ones((3,3),dtype=numpy.int8) >>>a 数组([[1,1,1], [1, 1, 1], [1,1,1]],dtype=int8) 使用范围索引返回长度为3的向量,使用整数索引返回3x3数组。前者在为索引数组赋值时抛出一个错误,后者工作正常


为什么会发生这种情况?

不同之处在于,在Python3.x中,range()生成迭代器而不是列表。在Python2.x之前,xrange()一直使用此功能。但是,现在,只需调用range()即可生成一个迭代器

您使用的是
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]])

使用范围与列表并不是这里的问题。