【问题标题】:Weird "too many indices for array" error in pythonpython中奇怪的“数组索引太多”错误
【发布时间】:2019-07-22 15:45:05
【问题描述】:

让我们创建一个包含 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:数组索引过多”。如果 n 大于或等于 32,则代码完美运行。无论初始数组的大小或单个切片的大小如何,都会发生错误,但始终使用数字 32。请注意,如果 n == 1,则代码有效。

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

【问题讨论】:

  • 你想用你的map做什么?我将给 [x...x+10) 为 [0...) 中的 a,即 [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] ...这可能不是您的意思.
  • 嗨医生爱,我想用地图做什么真的没关系。我已经更改了上面代码的描述。真正的问题是我在 n

标签: python numpy numpy-ndarray index-error


【解决方案1】:

您的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 版本有效。

【讨论】:

  • 谢谢。我也在玩, np.array(b) 确实使它起作用。
【解决方案2】:

首先,您不是切片 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 假定您希望将复杂列表作为引用序列,并将它们用作单独的索引数组,b 中每个叶元素一个 a 元素.

但是,一旦低于len(a) 的限制,numpy 就会假设您正在尝试将多维切片放入 ab 的每个元素都被视为切片a的对应维度。由于a 只是一维的,因此您会收到错误消息。您的代码将使用n=1 在此模式下运行,但使用n=2 及更高版本会失败。

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

【讨论】:

  • 嗨 Prune 感谢您的回答。你说的对。切片 0->9, 10-19 只是我随机选择的。真正的问题是我在 n
  • 您了解错误信息吗?我没有 n 更小,索引更少,b。问题是什么意思?
  • 代码失败,n 在 2-31 范围内,因为 b 足够小,可以解释为多维切片;这种解释优先。有关详细信息,请参阅链接的问题。当b 为 32 或更大时,唯一的法律解释是作为单个请求的序列。
  • 明白了。但是为什么它在 n = 32 及以上时会成功呢?
  • 查看您上面的评论。
猜你喜欢
  • 1970-01-01
  • 2018-03-04
  • 2019-11-16
  • 2015-09-20
  • 2017-08-13
  • 1970-01-01
  • 2016-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多