【问题标题】:Boolean indexing on multidimensionnal array多维数组中的布尔索引
【发布时间】:2018-04-01 09:55:45
【问题描述】:

我是 Python 和 Numpy 的新手。其实我只是在学习。

我正在阅读this tutorial,但我被困在这些行中:

>>> x = np.arange(30).reshape(2,3,5)
>>> x
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],
        [25, 26, 27, 28, 29]]])
>>> b = np.array([[True, True, False], [False, True, True]])
>>> x[b]
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [20, 21, 22, 23, 24],
       [25, 26, 27, 28, 29]])

我不明白我们是如何得出 x[b] 的结果的。

我也尝试猜测x[[False, False, False, True]]的结果

请解释一下,我是个新手。

【问题讨论】:

  • 也许你应该在深入 Numpy 之前花更多时间学习核心 Python ......但无论如何,b.shape 是 (2, 3),所以 b 中的每个 True 项目选择来自a 的一行。
  • 最简单的想象方法是将数据数组重新整形为二维数组:(6,5) 形状,然后使用扁平掩码数组从中选择行。
  • @PM2Ring 请您再说明一下。我迷路了:(
  • @cᴏʟᴅsᴘᴇᴇᴅ 认为我们需要一个更好的 dup 目标来讨论用于索引的布尔数组。
  • 看标题Boolean indexing on multidimensionnal array [NOT DUPLICATE] .......[duplicate]

标签: python numpy


【解决方案1】:

在底层,它从它映射的维度开始计算掩码覆盖的维度的下标索引(沿每个维度的索引),同时从未索引的轴中选择所有元素。

案例#1:3D 数据和2D 掩码

例如,对于二维的b,它映射到二维,因此对于x[b],它从第一个轴开始映射。

下标索引使用np.where/np.nonzero 计算 -

r,c = np.nonzero(b)

因此,x[b] 转换为:x[r,c,:] 或简称为:x[r,c]。所以,然后它使用advanced-indexing 从索引元组对中选择每个轴轴之外的元素 由rc 组成。

案例#2:4D 数据和2D 掩码

现在,让我们将数据数组的维数增加到4D,保持相同的2D 掩码,但索引盯着 从第二个轴开始,即x[:,b]

假设我们有:

x = np.arange(60).reshape(2,2,3,5)

获取下标索引,然后使用advanced-indexing -

r,c = np.nonzero(b)

所以,x[:,b] 应该与 x[:,r,c] 相同 -

In [148]: x = np.arange(60).reshape(2,2,3,5)

In [149]: b = np.array([[True, True, False], [False, True, True]])

In [150]: r,c = np.nonzero(b)

In [151]: np.allclose(x[:,b], x[:,r,c])
Out[151]: True

案例#3:4D 数据和3D 掩码

为了更深入,让我们考虑一个带有4D 数据数组的3D 掩码数组,并使用前面提出的所有理论进行验证 -

In [144]: x = np.arange(60).reshape(2,2,3,5)
     ...: b = np.random.rand(2,3,5)>0.5

In [146]: r,c,p = np.nonzero(b)

In [147]: np.allclose(x[:,b], x[:,r,c,p])
Out[147]: True

至于编辑:x[[False, False, False, True]],您仅使用长度为 5 的布尔数组沿第一个轴进行索引,而 x 的第一个轴的长度小于该长度,因此报告错误索引。

【讨论】:

  • 投了反对票,因为我认为这个答案对于“新手”来说太先进了。
  • @Stanko 好吧,如果不提供详细信息,您将无法完整回答。真的是投反对票的蹩脚借口。
【解决方案2】:

您在 1 个数组中有 3 个数组:

[
 [ 0,  1,  2,  3,  4],
 [ 5,  6,  7,  8,  9],
 [10, 11, 12, 13, 14]
]  

您的以下行:b = np.array([[True, True, False], ...]) 您说您想要保留前 2 行(前 2 个 True 值)并且您不想要最后一行(最后一个 False 值)。

另一部分的工作方式相同,1 个数组中有 3 个数组:

[
 [15, 16, 17, 18, 19],
 [20, 21, 22, 23, 24],
 [25, 26, 27, 28, 29]
]

您的b = np.array([..., [False, True, True]]) 行表示不保留第一行(因为第一个值为 False),但您想保留最后两行(最后两个值为 True)。

【讨论】:

  • 您还没有讨论过mask 的维度如何映射到数据数组的不同轴或更大的数据暗度。例如,如果我有:x[:,b],你会怎么做并且仍然保持解释的通用性。在某些时候,如果您要实际回答它,您将需要开始使用比仅行或“两部分”更好的术语。因此,被否决(我认为有足够的理由)。
  • 确实是一个很好的理由,我没有详细解释,但显然张贴者喜欢更简单的解释。也许现在由于我的回答,发布者对他的问题有了更好的理解,现在他会为你的回答等细节做好准备。
猜你喜欢
  • 2019-06-18
  • 2017-11-17
  • 2012-04-10
  • 2016-01-08
  • 2013-06-19
  • 2013-07-20
  • 2020-03-25
  • 2012-11-16
  • 1970-01-01
相关资源
最近更新 更多