ndarrays上的索引#

ndarrays上的索引#

整数数组索引#

整数数组索引允许根据其 N 维索引选择数组中的任意项。每个整数数组代表该维度中的多个索引。

索引数组中允许负值,其工作方式与单个索引或切片相同

>>> x = np.arange(10, 1, -1)

>>> x

array([10, 9, 8, 7, 6, 5, 4, 3, 2])

>>> x[np.array([3, 3, 1, 8])]

array([7, 7, 9, 2])

>>> x[np.array([3, 3, -3, 8])]

array([7, 7, 4, 2])

如果索引值超出范围,则会抛出 IndexError

>>> x = np.array([[1, 2], [3, 4], [5, 6]])

>>> x[np.array([1, -1])]

array([[3, 4],

[5, 6]])

>>> x[np.array([3, 4])]

Traceback (most recent call last):

...

IndexError: index 3 is out of bounds for axis 0 with size 3

当索引由与被索引数组的维度数量相同的整数数组组成时,索引是直接的,但与切片不同。

高级索引总是被广播并作为一个进行迭代

result[i_1, ..., i_M] == x[ind_1[i_1, ..., i_M], ind_2[i_1, ..., i_M],

..., ind_N[i_1, ..., i_M]]

请注意,结果形状与(广播后的)索引数组形状 ind_1, ..., ind_N 相同。如果索引无法广播到相同形状,则会引发异常 IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes...。

使用多维索引数组进行索引通常是较不寻常的用法,但它们是允许的,并且对于某些问题很有用。我们将从最简单的多维情况开始

>>> y = np.arange(35).reshape(5, 7)

>>> y

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, 30, 31, 32, 33, 34]])

>>> y[np.array([0, 2, 4]), np.array([0, 1, 2])]

array([ 0, 15, 30])

在这种情况下,如果索引数组具有匹配的形状,并且被索引数组的每个维度都有一个索引数组,则结果数组的形状与索引数组相同,并且值对应于索引数组中每个位置的索引集。在此示例中,两个索引数组的第一个索引值都为 0,因此结果数组的第一个值为 y[0, 0]。下一个值为 y[2, 1],最后一个为 y[4, 2]。

如果索引数组的形状不同,会尝试将它们广播到相同形状。如果它们无法广播到相同形状,则会引发异常

>>> y[np.array([0, 2, 4]), np.array([0, 1])]

Traceback (most recent call last):

...

IndexError: shape mismatch: indexing arrays could not be broadcast

together with shapes (3,) (2,)

广播机制允许将索引数组与其他索引的标量结合。其效果是标量值用于索引数组的所有相应值

>>> y[np.array([0, 2, 4]), 1]

array([ 1, 15, 29])

跳到下一个复杂级别,可以仅使用索引数组部分索引数组。理解在这种情况下会发生什么需要一些思考。例如,如果我们只使用一个索引数组与 y

>>> y[np.array([0, 2, 4])]

array([[ 0, 1, 2, 3, 4, 5, 6],

[14, 15, 16, 17, 18, 19, 20],

[28, 29, 30, 31, 32, 33, 34]])

这导致构造了一个新数组,其中索引数组的每个值从被索引数组中选择一行,结果数组的形状为(索引元素数量,行大小)。

通常,结果数组的形状将是索引数组的形状(或所有索引数组广播到的形状)与被索引数组中任何未使用维度(未被索引的维度)的形状的串联。

示例

从每一行中,应选择一个特定元素。行索引只是 [0, 1, 2],列索引指定了要为相应行选择的元素,这里是 [0, 1, 0]。将两者结合起来,可以使用高级索引解决此任务

>>> x = np.array([[1, 2], [3, 4], [5, 6]])

>>> x[[0, 1, 2], [0, 1, 0]]

array([1, 4, 5])

为了实现类似于上述基本切片的行为,可以使用广播。函数 ix_ 可以帮助实现此广播。这最好通过一个示例来理解。

示例

从一个 4x3 数组中,应使用高级索引选择角元素。因此,需要选择列为 [0, 2] 之一且行为 [0, 3] 之一的所有元素。要使用高级索引,需要显式地选择所有元素。使用之前解释的方法,可以写出

>>> x = np.array([[ 0, 1, 2],

... [ 3, 4, 5],

... [ 6, 7, 8],

... [ 9, 10, 11]])

>>> rows = np.array([[0, 0],

... [3, 3]], dtype=np.intp)

>>> columns = np.array([[0, 2],

... [0, 2]], dtype=np.intp)

>>> x[rows, columns]

array([[ 0, 2],

[ 9, 11]])

然而,由于上面的索引数组只是重复自身,因此可以使用广播(比较诸如 rows[:, np.newaxis] + columns 之类的操作)来简化这一点

>>> rows = np.array([0, 3], dtype=np.intp)

>>> columns = np.array([0, 2], dtype=np.intp)

>>> rows[:, np.newaxis]

array([[0],

[3]])

>>> x[rows[:, np.newaxis], columns]

array([[ 0, 2],

[ 9, 11]])

这种广播也可以使用函数 ix_ 来实现

>>> x[np.ix_(rows, columns)]

array([[ 0, 2],

[ 9, 11]])

请注意,如果没有调用 np.ix_,将只选择对角线元素

>>> x[rows, columns]

array([ 0, 11])

这种差异是关于使用多个高级索引进行索引时最重要的一点。

示例

高级索引可能有用的一种实际示例是颜色查找表,我们希望将图像的值映射到 RGB 三元组以进行显示。查找表可以具有形状 (nlookup, 3)。使用形状为 (ny, nx) 且 dtype=np.uint8(或任何整数类型,只要值在查找表的范围内)的图像索引此类数组,将生成形状为 (ny, nx, 3) 的数组,其中 RGB 三元组与每个像素位置相关联。

相关推荐

阳泉市有哪些App
Bet—288365

阳泉市有哪些App

📅 07-03 👁️ 6788
点痣祛斑杭州哪家医院好
365足球外围平台

点痣祛斑杭州哪家医院好

📅 07-09 👁️ 6118
soe是什麼公司
365官网国内怎么进

soe是什麼公司

📅 07-15 👁️ 1850
如何打开 FBX 文件
365足球外围平台

如何打开 FBX 文件

📅 07-18 👁️ 7018
俄罗斯世界杯球员评价:谁是最闪耀的球星?盘点2018年那些令人难忘的表现
阴阳师椒图哪里多?高效刷椒图地点推荐!
365足球外围平台

阴阳师椒图哪里多?高效刷椒图地点推荐!

📅 07-15 👁️ 9372