1

我明白如何

x=np.array([[1, 2], [3, 4], [5, 6]] 
y = x[[0,1,2], [0,1,0]] 

输出给出y= [1 4 5]这只是将第一个列表作为行和秒列表和列。

但是以下如何工作?

x = np.array([[ 0,  1,  2],[ 3,  4,  5],[ 6,  7,  8],[ 9, 10, 11]]) 

rows = np.array([[0,0],[3,3]])
cols = np.array([[0,2],[0,2]]) 
y = x[rows,cols] 

这给出了输出:

[[ 0  2]                                                                      
 [ 9 11]] 

你能解释一下使用 ndarrays 作为切片对象时的逻辑吗?为什么它对行和列都有一个二维数组。当切片对象是 ndarray 而不是 python 列表时,规则有何不同?

4

3 回答 3

1

我们有以下数组x

x = np.array([[1, 2], [3, 4], [5, 6]] 

以及索引[0, 1, 2][0, 1, 0]索引时x

x[[0,1,2], [0,1,0]] 

[1,  4,  5]

我们使用的索引基本上可以转换为:

[0, 1, 2] & [0, 1, 0] --> [0,0], [1,1], [2,0]

由于我们使用一维列表作为索引,我们得到一维数组作为结果。


有了这些知识,让我们看看下一个案例。现在,我们将数组x设为:

x = np.array([[ 0,  1,  2],[ 3,  4,  5],[ 6,  7,  8],[ 9, 10, 11]]) 

现在索引是二维数组。

rows = np.array([[0,0],[3,3]])
cols = np.array([[0,2],[0,2]]) 

当索引到数组中时,x如下所示:

x[rows,cols] 

简单翻译为:

[[0,0],[3,3]]
  | |   | |      ====> [[0,0]], [[0,2]], [[3,0]], [[3,2]]
[[0,2],[0,2]]

现在,很容易观察到这 4 个list of list索引到数组中时如何x给出以下结果(即,这里它只是从我们的数组中返回角元素x):

[[ 0,  2]                                                                      
 [ 9, 11]]

请注意,在这种情况下,我们将结果作为 2D 数组(与第一种情况下的 1D 数组相反),因为我们的索引rows&columns本身是 2D 数组(即等效地list of list),而在第一种情况下,我们的索引是 1D 数组(或等效地简单list没有任何嵌套)。

因此,如果您需要二维数组作为结果,则需要将二维数组作为索引。

于 2018-01-11T15:03:08.857 回答
1

了解这一点的最简单方法是以下观察:输出的形状由索引数组的形状决定,或者更准确地说,由将所有索引数组广播在一起所产生的形状决定。

像这样看:你有一个A给定形状的数组和另一个形状的数组V,你想AV. 你需要指定什么?好吧,对于中的每个位置,A您都需要指定 中某些元素的坐标V。因此,如果V是 ND,您需要 N 个与该形状相同A或至少可广播的索引数组。然后V通过将这些索引数组放在[]表达式中的坐标位置来进行索引。

于 2018-01-11T13:19:41.120 回答
1

为了简单起见,我们将保持 2D 并假设rows.shape= cols.shape。(你可以通过广播打破这条规则,但现在我们不会)。我们称这个形状(I, J)

那么y = x[rows, cols]是一样的:

y = np.empty((I, J))
for i in range(I):
    for j in range(J):
        y[i, j] = x[rows[i, j], cols[i, j]]
于 2018-01-11T13:19:55.253 回答