为什么NumPy高级索引在列表和NumPy数组中产生不同的结果?

3

我有一个关于NumPy高级索引的问题。

我发现了这个问题,但我猜我的问题稍微有点不同。

在下面的示例中,x_array是预期的结果。但是当我使用一个列表时,结果会有所不同。

从numpy文档中得知:

当选择对象obj为非元组序列对象、ndarray(数据类型为整数或布尔型)或至少包含一个序列对象或ndarray(数据类型为整数或布尔型)的元组时,就会触发高级索引。高级索引有两种类型: 整数和布尔类型。

import numpy as np

vertices = np.arange(9).reshape((3,3))

idx_list = [[0, 1, 2],
            [0, 2, 1]]

x_list = vertices[idx_list]

print('list')

print(x_list)

#this works as expected
idx_array = np.array(idx_list)
x_array = vertices[idx_array]

print('array')
print(x_array)

idx_list应该触发高级索引,因为它是一个“非元组序列对象”?还是列表和元组在这里相同,并且它是“至少有一个序列对象的元组”

使用列表与将两个列表条目用逗号分隔放在方括号中(每个维度一个)的结果相同。

x_list_2 = vertices[idx_list[0], idx_list[1]] 

这也是我期望的行为。


2
这是一个由于历史原因尚未清理的不一致性;可能存在旧代码期望这种行为。 - hpaulj
那么这个问题和上面提到的链接是一样的吗? - Joe
在我的回答链接中的某些地方,有一段代码引用(通过 @Eric)关于“嵌入序列的序列”的示例,就像你的一样。vertices[idx_list], :]明确告诉它将idx_list应用于第一维,否则它会将其视为“索引元组”。 - hpaulj
那么 Sequences < NPY_MAXDIMS 中的 Sequences 是指 len(idx_list) 还是方括号中参数的数量,例如 x[arg1, arg2] - Joe
在编程中,自己回答自己的问题总是没问题的。 - uhoh
2个回答

0

你的答案没有解释任何事情。以下是一些想法:

首先,由于您的 idx_list 的维度为 2 ,背景中做了一些事情:

idx_list = [[0, 1, 2],
            [0, 2, 1]]

x_list = vertices[tuple(idx_list)]  # wrapping with a `tuple()`

如果您明确地这样做,您可以摆脱(烦人的)FutureWarning

FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.

(这是对您原始问题的回答)其次,您期望的行为(x_arrayshape(2,3,3)):

[[[0 1 2]
  [3 4 5]
  [6 7 8]]

 [[0 1 2]
  [6 7 8]
  [3 4 5]]]

可以按照您的原始帖子中提到的任意一种方式完成:

vertices[np.array(idx_list)]

或者也可以通过列表:

vertices[tuple([list])]
# or this shorthand with warning
# vertices[[list]]

请注意,我已经添加了一个额外的括号([list]),以确保结果元组的第一个组件的维度为2,这将产生与np.array(idx_list)相同的含义。

0

最终归结于https://dev59.com/wpzha4cB1Zd3GeqPF3xF#40599589中提到的内容。

从numpy的索引文档中可以看到:

为了保持与Numeric中常见用法的向后兼容性, 如果选择对象是任何非ndarray序列(如列表), 包含切片对象、省略号对象或newaxis对象,则也会启动基本切片, 但不适用于整数数组或其他嵌入序列。

列表示例触发了向后兼容性逻辑的一个未记录部分,正如源代码中的注释所描述的那样:

/*
 * Sequences < NPY_MAXDIMS with any slice objects
 * or newaxis, Ellipsis or other arrays or sequences
 * embedded, are considered equivalent to an indexing
 * tuple. (`a[[[1,2], [3,4]]] == a[[1,2], [3,4]]`)
 */

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