我以以下数组为例:
lights = np.array([ [1,0,1], [0,1,1], [0,0,1], [1,1,1] ])
lights[0]
返回一个形状:(3,)
lights[0:1]
返回一个形状:(1, 3)
在这种情况下,我不明白numpy的逻辑是什么。假设切片是互斥的,[0:1]类似于[0]。那么,为什么它会影响数组的形状呢?
https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#basic-切片和索引
整数i返回的值与i:i+1相同,只是返回对象的维度减少了1。特别是,第p个元素为整数的选择元组(以及所有其他条目:(返回维度为N-1的相应子数组。如果N=1,则返回的对象是数组标量。这些对象在标量中进行了解释。
这种使用标量与切片的numpy
索引与Python的列表索引一致:
In [119]: alist = [ [1,0,1], [0,1,1], [0,0,1], [1,1,1] ]
In [120]: alist[0]
Out[120]: [1, 0, 1] # one element of alist
In [121]: alist[0:1]
Out[121]: [[1, 0, 1]] # a list with one element
In [122]: alist[0][1] # nested selection of a number
Out[122]: 0
数组相等,匹配使用[]:
In [123]: arr = np.array(alist)
In [124]: arr
Out[124]:
array([[1, 0, 1],
[0, 1, 1],
[0, 0, 1],
[1, 1, 1]])
In [125]: arr[0]
Out[125]: array([1, 0, 1])
In [126]: arr[0:1]
Out[126]: array([[1, 0, 1]])
In [127]: arr[0,1]
Out[127]: 0
numpy
还可以使用元组、列表和数组进行索引。
lights
是形状为(4,3)
的二维数组。
在lights[0]
的情况下,您需要该数组的第一个元素,它本身就是一个大小为3的1d数组。因此得到了形状(3,)
。
现在有了lights[0:1]
,你就不会这么做了。你切出一个子阵列。即使这个子数组在一维中只包含一个元素,它仍然是一个二维数组。
问问自己:如果你做lights[0:2]
,会发生什么?你会期望一个形状为(2,3)
的二维阵列,对吧?因此,即使lights[0:1]
返回的子数组可能与1d数组相同,NumPy也不能为您删除该维度。
如果您键入类似lights[0:N]
的内容,其中N是一个变量,如果N=1
,NumPy会自动删除1维,则每次都必须单独处理这种特殊情况。举个简单的例子,你想得到一个切片,并设置它的第二个元素:
N = 2
t = lights[0:N]
t[0, 1] = 42
您可以将N设置为1,它仍然有效。现在将其更改为t = lights[0]
,您的程序将在下一行崩溃,因为您的数组只有一维。因此,如果NumPy会删除lights[0:1]
的额外维度,那么每次都必须为这种特殊情况编写额外的代码。