numpy 多维数组索引

numpy multidimensional array indexing

我在 numpy 多维数组中进行索引时遇到一个奇怪的问题。所以,我有一个形状数组 (4, 882)。我有另一个数组,称为形状匹配 (276, 2)。此匹配数组包含我的原始多维数组中有效条目的索引。我想要做的是 select 前 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]]

这很好用。所以,这实际上是先 select 行的子集,然后是列,但我不确定为什么我的第一次尝试是错误的。另外,做:

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

当然有效。

错误消息有点令人困惑,因为形状不匹配不在 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. 将索引列表更改为二维列表,其形状可以广播反对m:

    >>> k[[[1], [0]],m[:, 0]]
    array([[ 8, 10, 12, 14],
           [ 0,  2,  4,  6]])
    
  2. 将其转换为数组并重塑数组:

    >>> k[numpy.array([1, 0]).reshape(2, 1),m[:, 0]]
    array([[ 8, 10, 12, 14],
           [ 0,  2,  4,  6]])
    
  3. 将其转换为数组并使用 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] 列表成为 "column array,",您可以使它们可广播。当您尝试将 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]])