使用列表切片数组

8
因此,我创建了一个numpy数组:
a = np.arange(25).reshape(5,5)
array([[ 0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10,11,12,13,14], [15,16,17,18,19], [20,21,22,23,24]])
传统的切片 a[1:3,1:3] 返回
array([[6,7], [11,12]])
使用第二个列表也是这样 a[1:3,[1,2]]
array([[6,7], [11,12]])
然而,a[[1,2],[1,2]] 返回
array([6,12])
显然我在这里理解有误。话虽如此,在某些情况下,使用列表进行切片可能非常有用。
干杯, keng

a[[1,2],[1,2]] 应该改为 a[[1:2],[1:2]] 吗?a[1:3,[1,2]] 中有错别字吗?还是我理解有误? - SherylHohman
4个回答

2
您观察到了所谓的高级索引的效果。让我们考虑一下链接中的示例:
import numpy as np
x = np.array([[1, 2], [3, 4], [5, 6]])
print(x)
[[1 2]
 [3 4]
 [5 6]]
print(x[[0, 1, 2], [0, 1, 0]])  # [1 4 5]

您可以将其视为提供网格的(笛卡尔)坐标列表,如下所示:
print(x[0,1])  # 1
print(x[1,1])  # 4
print(x[2,0])  # 5

0
在最后一种情况下,两个单独的列表被视为独立的索引操作(这确实是很笨拙的措辞,请耐心等待)。
Numpy看到两个由两个整数组成的列表,并决定您因此要求两个值。每个值的行索引来自第一个列表,而每个值的列索引来自第二个列表。因此,您将获得a[1, 1]a[2, 2]。冒号符号不仅扩展到您准确推断的列表,还告诉numpy您想要该范围内的所有行/列。
如果您提供手动筛选的列表索引,则它们必须具有相同的大小,因为每个/任何列表的大小都是您将获得的元素数量。例如,如果您想要行1,2,3中列1和2中的元素:
>>> a[1:4,[1,2]]
array([[ 6,  7],
       [11, 12],
       [16, 17]])

但是

>>> a[[1,2,3],[1,2]]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (3,) (2,)

前者告诉numpy您想要一系列行和特定列,而后者则表示“获取(1,1)(2,2)(3,嘿!其他索引在哪里?)处的元素”。

0

a[[1,2],[1,2]] 的意思是,我想要 a[1,1] 和 a[2,2]。有几种方法可以解决这个问题,我可能甚至没有最好的方法,但你可以尝试一下。

a[[1,1,2,2],[1,2,1,2]]

这将为您提供上述内容的扁平化版本

a[[1,2]][:,[1,2]]

这将为您提供正确的切片,它将使用行[1,2]和列[1,2]来工作。


0

它触发高级索引,因此第一个切片是行索引,第二个是列索引。对于每一行,它选择相应的列。

a[[1,2], [1,2]] -> [a[1, 1], a[2, 2]] -> [6, 12]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接