使用逻辑索引从2D数组中提取子数组 - Python。

3

我正在尝试使用逻辑索引提取子数组,如下所示:

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根据a中的每个元素对b的逻辑索引进行评估。 然而,在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]])

你在寻找:a[b][:,b]吗? - not_speshal
MATLAB使得索引块变得容易,但是获取“对角线”[6,16]有点困难,需要使用sub2ind(或类似的方法)来生成等效压缩矩阵的索引。而在numpy中则相反。你的[b,b]选择了一对;获取块需要额外的步骤(最简单的方法是使用np.ix_)。 - hpaulj
3个回答

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

2
你可以在这里使用 np.ix_
a[np.ix_(b, b)]

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

np.ix_返回的输出

>>> np.ix_(b, b)
(array([[1],
        [3]]),
 array([[1, 3]]))

0
你可以利用 b 向量的外积。通过求和 True 值的数量,您可以获得新的维度。
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]]

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