首页 > 解决方案 > 多维索引切片后数组的维度

问题描述

我想使用索引切片沿其 2 个轴对多维 numpy 数组(> 2 维)进行切片。每个原始维度的最终位置的规则是什么?


为了说明我的问题,让我举一个例子。假设我们有一个 4D 数组:

import numpy as np

a = np.arange(2*3*4*5).reshape(2,3,4,5)

我将使用 numpy.where 创建一个索引元组,用于沿轴 1 和 3 进行切片:

mask = np.where(np.random.rand(3,5) > 0.5)

这将从我的数组中挑选出随机切片a。假设它返回长度为 7 的元组。为了保留剩余的维度,我将使用slice(None)对象:

b = a[(slice(None), mask[0], slice(None), mask[1])]

这改变了形状:

>>> a.shape
(2, 3, 4, 5)
>>> b.shape
(7, 2, 4)

未触及的轴(即使用slice(None)对象切片)似乎已被保留,而切片的轴被破坏并且生成的轴被移动到前面。

然而,这并非总是如此。当我将蒙版应用于轴 1 和轴 2 时:

mask2 = np.where(np.random.rand(3,4) > 0.5)
c = a[(slice(None), mask[0], mask[1], slice(None))]

我观察到以下内容(numpy.where 再次返回了长度为 7 的元组):

>>> c.shape
(2, 7, 5)

被切片破坏的轴产生的轴这次没有移动到前面。

我的猜测是它与切片轴是否相邻有关,但我想知道这种行为是从什么规则出现的。

标签: pythonarraysnumpyslicedimension

解决方案


https://docs.scipy.org/doc/numpy-1.15.4/reference/arrays.indexing.html#combining-advanced-and-basic-indexing

如果应用于二维数组,您的where蒙版将生成一维形状数组,条件为真的值。(7,)您将其表述为“摧毁”一对轴。

在第二种情况下,7可以放在2和之间5

但在第一个它是模棱两可的,因为中间的切片(非邻接) - 后备规则是把它放在第一位,然后对切片进行排序。换句话说,它不会尝试在 (2,7,4) 和 (2,4,7) 顺序之间进行选择,而是选择 (7,2,4)。

在这种情况下,歧义是明确的,默认是合理的。它更复杂,一个或多个维度被标量索引消除。


推荐阅读