切片numpy arrayx时形状发生变化



我以以下数组为例:

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]的额外维度,那么每次都必须为这种特殊情况编写额外的代码。

最新更新