我目前正在学习Python,偶然发现了一个在执行基本数组切片命令时让我感到困惑的结果。
我使用此命令创建了一个4x5矩阵:
>>> a = numpy.arange(20).reshape(4,5)
给出了:
[[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10,11,12,13,14],
[15,16,17,18,19]]
如果我像这样索引数组:
>>> a[0:3, 2]
我得到一个行向量:
[2, 7, 12]
但是如果我像这样索引数组:
>>> a[0:3, 2:3]
我得到一个列向量:
[[ 2],
[ 7],
[12]]
当插入两个命令时我期望结果是相同的,那么为什么我会得到不同类型的向量?
谢谢!
答案 0 :(得分:2)
tl; dr version
在numpy中,从数组中沿着维度获取单个索引会将维度减少1,因此从2D数组中获取索引会生成1D数组(第一种情况)。沿着维度采取切片保持相同的维度,即使切片的长度为1,因此采用2D数组的长度为1的切片仍然是2D数组(第二种情况)
详细版本
问题是第一个结果不是行向量,而是一维数组。当您从维度中获取单个标量索引时,它会将维数减少1.因此,从4D阵列获取标量索引会使其成为3D阵列,从3D阵列中取一个使其成为2D阵列,将2D阵列转换为1D数组,1D数组到标量。
这是为了保持一致。如果从一维数组中获取一个项目会产生一个标量(将维度减少一个),那么通过扩展,高维等效操作应该以相同的方式运行。
在第二种情况下,你正在切片,而不是标量。当您这样做时,它会保留维度数。因此,即使切片为空(或者在您的情况下为长度1),切片2D数组也始终是2D数组。这也是为了保持一致性。如果2D阵列的长度为3的切片是2D阵列,并且2D阵列的长度为2的切片是2D阵列,则2D阵列的长度为1的切片也应该是2D阵列。
这也是一个方便的约定,因为它允许您只是在几个字符中明确定义是否要降低维度。
有些语言,如MATLAB,没有一维数组(或技术上,矩阵)的概念,数组可以是0D(标量),2D,3D等,但不是1D。另一方面,Python允许使用真正的一维数组,这可能会让那些不习惯它的人绊倒。
答案 1 :(得分:1)
如果使用两个切片,则会得到两个维度。虽然你在第二个例子中得到的东西有时被称为"列向量",但它实际上是一个二维的Nx1数组。这与你在第一个例子中得到的不同,第一个例子根本不是二维的,而是一维数组。
使用切片而不是单个值的事实是导致额外维度的原因。 Numpy并没有看到切片实际抓取的元素数量;它只是看你是否使用了切片。如果a[0:3, 2:3]
返回1D向量,但a[0:3, 1:3]
返回了2D数组,则会更加混乱。
答案 2 :(得分:-1)
为什么有不同的命令。
在第一种情况下,您获得前三行,其中包含第三行元素。这将只返回元素。
在第二种情况下,您获得前三行并指定第三列的两个元素。此列将返回它,或带有一个元素的向量