“带有广播和布尔掩码的花式索引如何工作?

问题描述 投票:0回答:1

我在Jake Vanderplas的《数据科学手册》中遇到了这段代码。对我来说,将广播与花式索引一起使用的概念尚不清楚。请解释。

In[5]: X = np.arange(12).reshape((3, 4))
 X
Out[5]: array([[ 0, 1, 2, 3],
 [ 4, 5, 6, 7],
 [ 8, 9, 10, 11]])

In[6]: row = np.array([0, 1, 2])
 col = np.array([2, 1, 3])

In[7]: X[row[:, np.newaxis], col]
Out[7]: array([[ 2, 1, 3],
               [ 6, 5, 7],
              [10, 9, 11]])

它说:“这里,每个行值都与每个列向量匹配,就像我们在广播算术运算时所看到的那样。例如:“

In[8]: row[:, np.newaxis] * col
Out[8]: array([[0, 0, 0],
               [2, 1, 3],
               [4, 2, 6]])
python arrays numpy masking numpy-broadcasting
1个回答
0
投票

如果使用整数数组来索引另一个数组您基本上可以遍历给定的索引,并沿要索引的轴选择相应的元素(可能仍然是数组),并将它们堆叠在一起。

arr55 = 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]])

arr53 = arr55[:, [3, 3, 4]]  
# pick the elements at (arr[:, 3], arr[:, 3], arr[:, 4])
# array([[ 3,  3,  4],
#        [ 8,  8,  9],
#        [13, 13, 14],
#        [18, 18, 19],
#        [23, 23, 24]])

因此,如果使用长度为(m, n)(或长度为k)的行(或列)索引来索引l数组,则结果形状为:

A_nm[row, :] -> A_km
A_nm[:, col] -> A_nl

但是如果您使用两个数组rowcol来索引一个数组您可以同时遍历两个索引,并将各个位置的元素(可能仍然是数组)堆叠在一起。在此rowcol必须具有相同的长度。

A_nm[row, col] -> A_k
array([ 3, 13, 24])

arr3 = arr55[[0, 2, 4], [3, 3, 4]]  
# pick the element at (arr[0, 3], arr[2, 3], arr[4, 4])

现在终于可以提出您的问题了:在对数组建立索引时可以使用广播。有时不希望仅元素

(arr[0, 3], arr[2, 3], arr[4, 4])

被选择,而是扩展版本:

(arr[0, [3, 3, 4]], arr[2, [3, 3, 4]], arr[4, [3, 3, 4]])
# each row value is matched with each column vector

此匹配/广播与其他算术运算完全相同。但是,此处的示例在某种意义上可能是不好的,因为所示乘法的结果对索引不是很重要。这里的重点是组合和结果形状:

row * col  
# performs a element wise multiplication resulting in 3 
numbers
row[:, np.newaxis] * col 
# performs a multiplication where each row value is *matched* with each column vector

该示例希望强调rowcol的这种匹配。

我们可以看一下并尝试各种可能性:

n = 3
m = 4
X = np.arange(n*m).reshape((n, m))
row = np.array([0, 1, 2])  # k = 3
col = np.array([2, 1, 3])  # l = 3

X[row, :]  # A_nm[row, :] -> A_km
# array([[ 0,  1,  2,  3],
#        [ 4,  5,  6,  7],
#        [ 8,  9, 10, 11]])

X[:, col]  # A_nm[:, col] -> A_nl
# array([[ 2,  1,  3],
#        [ 6,  5,  7],
#        [10,  9, 11]])

X[row, col]  # A_nm[row, col] -> A_l == A_k
# array([ 2,  5, 11]

X[row, :][:, col]  # A_nm[row, :][:, col] -> A_km[:, col] -> A_kl 
# == X[:, col][row, :]
# == X[row[:, np.newaxis], col]  # A_nm[row[:, np.newaxis], col] -> A_kl 
# array([[ 2,  1,  3],
#        [ 6,  5,  7],
#        [10,  9, 11]])

X[row, col[:, np.newaxis]]
# == X[row[:, np.newaxis], col].T
# array([[ 2,  6, 10],
#        [ 1,  5,  9],
#        [ 3,  7, 11]])

© www.soinside.com 2019 - 2024. All rights reserved.