使用逻辑索引从二维数组中提取子数组 - python

Extract sub-array from 2D array using logical indexing - python

我正在尝试使用逻辑索引提取子数组,

a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
a
Out[45]: 
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12],
       [13, 14, 15, 16]])
b = np.array([False, True, False, True])
a[b, b]
Out[49]: array([ 6, 16])

python 计算 b 中每个 a 元素的逻辑索引。但是在 matlab 中你可以做类似

的事情
>> a = [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16]

a =

     1     2     3     4
     5     6     7     8
     9    10    11    12
    13    14    15    16

>> b = [2 4]

b =

     2     4

>> a(b, b)

ans =

     6     8
    14    16

如何在 python 中实现相同的结果而不用做,

c = a[:, b]
c[b,:]
Out[51]: 
array([[ 6,  8],
       [14, 16]])

您可以在此处使用 np.ix_

a[np.ix_(b, b)]

# array([[ 6,  8],
#        [14, 16]])

np.ix_

返回的输出
>>> np.ix_(b, b)
(array([[1],
        [3]]),
 array([[1, 3]]))

Numpy 支持逻辑索引,尽管它与您在 MATLAB 中熟悉的有点不同。要获得您想要的结果,您可以执行以下操作:

a[b][:,b]  # first brackets isolates the rows, second brackets isolate the columns
Out[27]: 
array([[ 6,  8],
       [14, 16]])

在您了解您的案例中发生的事情之后,您将了解更多“numpy”方法。 b = np.array([False, True, False, True]) 类似于 b=np.array([1,3]) 并且我会更容易解释。当写 a[[1,3],[1,3]] 时,numpy 会创建一个 (2,1) 形状数组,并将 a[1,1] 放在 [0] 位置,将 a[3,3] 放在第二个位置。要创建形状 (2,2) 的输出,索引必须具有相同的维度。因此,以下将得到您的结果:

a[[[1,1],[3,3]],[[1,3],[1,3]]]
Out[28]: 
array([[ 6,  8],
       [14, 16]])

解释:

索引数组是:

temp_rows = np.array([[1,1],
                      [3,3]])
temp_cols = np.array([[1,3],
                      [1,3])

两个数组的维度均为 (2,2),因此,numpy 将创建形状为 (2,2) 的输出。然后,它将a[1,1]放在位置[0,0],a[1,3]放在[0,1],a[3,1]放在位置[1,0],a[3,3]放在位置[ 1,1]。这可以扩展为任何形状,但出于您的目的,您需要 (2,2)

的形状

弄清楚这一点后,如果你在第一维插入一个 (2,1) 数组,在第二维插入一个 (1,2) 数组,numpy 将执行广播,类似于 MATLAB 操作。这意味着通过使用:

temp_rows = np.array([[1],[3]])
temp_cols = np.array([1,3])

你可以做到:

a[[[1],[3]], [1,3])
Out[29]: 
array([[ 6,  8],
       [14, 16]])

您可以使用 b 向量的外积。您可以使用总和从真值的数量获得新的维度。

import numpy as np
a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
b = np.array([False, True, False, True])
#
M = np.outer(b, b)
new_dim = b.sum()
new_shape = (new_dim, new_dim)

selection = a[M].reshape(new_shape)

结果看起来像

[[ 6  8]
 [14 16]]