python 中的奇怪 "too many indices for array" 错误

Weird "too many indices for array" error in python

让我们创建一个包含 10,000 个条目的大型 np 数组'a'

import numpy as np
a = np.arange(0, 10000)

让我们用 'n' 索引 0->9、1->10、2->11 等对数组进行切片

n = 32
b = list(map(lambda x:np.arange(x, x+10), np.arange(0, n)))
c = a[b]

我遇到的奇怪事情是,如果 n 小于 32,我会得到一个错误 "IndexError: too many indices for array"。如果 n 大于或等于 32,则代码可以完美运行。无论初始数组的大小或单个切片的大小如何,都会发生错误,但始终使用数字 32。请注意,如果 n == 1,则代码有效。

知道是什么原因造成的吗?谢谢。

首先,您不是切片 0->9、10->19、20->29;您的切片仅前进 1:0->9、1->10、11->20。相反,试试这个:

n = 32
size = 10
b = list(map(lambda x:np.arange(x, x+size), np.arange(0, n*size, size)))

接下来,您误用了索引符号。 b 是一个数组列表,您已经使用这个 整个 列表来索引 a。当您索引的元素多于 a 中存在的元素时,numpy 假定您希望将复杂列表作为引用序列,并将它们用作单独的索引数组,每个元素一个 a b.

中的叶元素

但是,一旦低于 len(a) 的限制,则 numpy 假设您正在尝试将多维切片放入 a:[ 的每个元素=11=]作为a对应维度的切片。由于 a 只是一维的,您会收到错误消息。您的代码将在 n=1 的这种模式下 运行,但在 n=2 及更高版本时失败。

虽然您的问题不是重复的,但也请参阅

您的 b 是数组列表:

In [84]: b = list(map(lambda x:np.arange(x, x+10), np.arange(0, 5)))            
In [85]: b                                                                      
Out[85]: 
[array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
 array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10]),
 array([ 2,  3,  4,  5,  6,  7,  8,  9, 10, 11]),
 array([ 3,  4,  5,  6,  7,  8,  9, 10, 11, 12]),
 array([ 4,  5,  6,  7,  8,  9, 10, 11, 12, 13])]

用作索引时:

In [86]: np.arange(1000)[b]                                                     
/usr/local/bin/ipython3:1: 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.
  #!/usr/bin/python3
---------------------------------------------------------------
IndexError: too many indices for array

A[1,2,3]A[(1,2,3)] 相同 - 也就是说,逗号分隔的索引是一个元组,然后传递给索引函数。或者换句话说,多维索引应该是一个元组(包括带有切片的元组)。

到现在为止numpy有点马虎,让我们以同样的方式使用索引列表。该警告告诉我们开发人员正在收紧这些限制。

错误意味着它试图将列表中的每个数组解释为单独维度的索引。一个数组最多可以有 32 个维度。显然,对于较长的列表,它不会尝试将其视为元组,而是创建一个二维数组用于索引。

我们可以通过多种方式使用您的 b 来索引一维数组:

In [87]: np.arange(1000)[np.hstack(b)]                                          
Out[87]: 
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  1,  2,  3,  4,  5,  6,  7,
        8,  9, 10,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,  3,  4,  5,  6,
        7,  8,  9, 10, 11, 12,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13])

In [89]: np.arange(1000)[np.array(b)]    # or np.vstack(b)                                       
Out[89]: 
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10],
       [ 2,  3,  4,  5,  6,  7,  8,  9, 10, 11],
       [ 3,  4,  5,  6,  7,  8,  9, 10, 11, 12],
       [ 4,  5,  6,  7,  8,  9, 10, 11, 12, 13]])

In [90]: np.arange(1000)[b,]             # 1d tuple containing b                                       
Out[90]: 
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10],
       [ 2,  3,  4,  5,  6,  7,  8,  9, 10, 11],
       [ 3,  4,  5,  6,  7,  8,  9, 10, 11, 12],
       [ 4,  5,  6,  7,  8,  9, 10, 11, 12, 13]])

请注意,如果 b 是参差不齐的列表 - 一个或多个数组较短,则只有 hstack 版本有效。