NumPy多维数组索引

3

当我在numpy多维数组中进行索引时,遇到了一个奇怪的问题。我的数组形状为(4, 882)。我有另一个名为matches的数组,形状为(276, 2)。这个匹配数组保存了原始多维数组中有效条目的索引。我想要做的是选择第一行和第二行,并选择匹配匹配数组中索引的所有列。因此,我执行以下操作:

import numpy as np
k = get_array()  # This has shape (4, 882)
m = get_match()  # This has shape (276, 2)

s = k[[1, 0], m[:, 0]]

这会导致错误:

ValueError: shape mismatch: objects cannot be broadcast to a single shape

然而,当我执行以下操作:
s = k[[1, 0], :][:, m[:, 0]]

这个方法很好用。因此,它首先选择了行的子集然后再选择列,但我不确定为什么我的第一个尝试是错误的。同时,进行以下操作:

s = k[[1, 0], :]

当然可以。
1个回答

2
错误消息有点令人困惑,因为形状不匹配不是在km之间。而是在[1, 0]m[:,0]之间。以下是三种使用以下(更容易可视化)数组修复它的方法:
>>> k
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]])
>>> m
array([[0, 1],
       [2, 3],
       [4, 5],
       [6, 7]])
  1. Change the indexing list to a 2-d list with a shape that can be broadcasted against m:

    >>> k[[[1], [0]],m[:, 0]]
    array([[ 8, 10, 12, 14],
           [ 0,  2,  4,  6]])
    
  2. Convert it to an array and reshape the array:

    >>> k[numpy.array([1, 0]).reshape(2, 1),m[:, 0]]
    array([[ 8, 10, 12, 14],
           [ 0,  2,  4,  6]])
    
  3. Convert it to an array and slice it using numpy.newaxis, a.k.a. None:

    >>> k[numpy.array([1, 0])[:,None],m[:, 0]]
    array([[ 8, 10, 12, 14],
           [ 0,  2,  4,  6]])
    

还有很多其他的内容,但这三个是最容易想到的。

您之所以会出现错误是因为numpy需要传递相同形状的索引,或者可以广播到相同形状。通过将[1, 0]列表创建成“列数组”,您就可以将它们广播了。当您尝试将m乘以[1, 0]时也会发生同样的事情:

>>> m[:,0] * [0, 1]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: shape mismatch: objects cannot be broadcast to a single shape

所有的修复方法都适用。例如:

>>> m[:,0] * [[0], [1]]
array([[0, 0, 0, 0],
       [0, 2, 4, 6]])

最后,需要注意的是,您也可以通过传递一个形状不同的m切片来修复它 -- 请注意输出已经被转置:

>>> k[[1, 0],m[:, 0:1]]
array([[ 8,  0],
       [10,  2],
       [12,  4],
       [14,  6]])

哇,非常感谢您提供如此详细的答案...我已经为此苦恼了至少一个小时! - Luca
这在文档中被描述为“高级索引”。 - hpaulj

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