TypeError:只有整数标量数组可以转换为带有1D numpy indices数组的标量索引

3ya*_*bos 14 python numpy python-3.x

我想编写一个函数,从训练集中随机选取元素,但是基于提供的bin概率.我将设置索引除以11个bin,然后为它们创建自定义概率.

bin_probs = [0.5, 0.3, 0.15, 0.04, 0.0025, 0.0025, 0.001, 0.001, 0.001, 0.001, 0.001]

X_train = list(range(2000000))

train_probs = bin_probs * int(len(X_train) / len(bin_probs)) # extend probabilities across bin elements
train_probs.extend([0.001]*(len(X_train) - len(train_probs))) # a small fix to match number of elements
train_probs = train_probs/np.sum(train_probs) # normalize
indices = np.random.choice(range(len(X_train)), replace=False, size=50000, p=train_probs)
out_images = X_train[indices.astype(int)] # this is where I get the error
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

TypeError: only integer scalar arrays can be converted to a scalar index with 1D numpy indices array
Run Code Online (Sandbox Code Playgroud)

我发现这很奇怪,因为我已经检查了我创建的索引数组,它是1-D,它是整数,它是标量.

我错过了什么?

注:我试图通过indices使用astype(int).同样的错误.

小智 73

每当我使用np.concatenate错误的方式时,我都会收到此错误:

>>> a = np.eye(2)
>>> np.concatenate(a, a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<__array_function__ internals>", line 6, in concatenate
TypeError: only integer scalar arrays can be converted to a scalar index
Run Code Online (Sandbox Code Playgroud)

正确的方法是将两个数组作为元组输入:

>>> np.concatenate((a, a))
array([[1., 0.],
       [0., 1.],
       [1., 0.],
       [0., 1.]])
Run Code Online (Sandbox Code Playgroud)

  • 我也陷入了同样的陷阱。很容易忽视 np.concatenate() 的要求,即要连接的数组必须作为元组提供。非常感谢! (8认同)
  • Duuude,你救了我的命:) 谢谢 (3认同)

DYZ*_*DYZ 37

也许错误信息有点误导,但要点是X_train列表,而不是numpy数组.您不能在其上使用数组索引.首先使它成为一个数组:

out_images = np.array(X_train)[indices.astype(int)]
Run Code Online (Sandbox Code Playgroud)

  • 这为我节省了很多排除故障的时间!(这是一个非常具有误导性的错误消息) (10认同)
  • 如果坚持“X_train”和“out_images”必须保留为列表,另一种方法是使用列表理解。`out_images = [X_train[index] 用于索引中的索引]` (2认同)

hpa*_*ulj 8

生成此错误消息的简单案例:

In [8]: [1,2,3,4,5][np.array([1])]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-8-55def8e1923d> in <module>()
----> 1 [1,2,3,4,5][np.array([1])]

TypeError: only integer scalar arrays can be converted to a scalar index
Run Code Online (Sandbox Code Playgroud)

一些有效的变体:

In [9]: [1,2,3,4,5][np.array(1)]     # this is a 0d array index
Out[9]: 2
In [10]: [1,2,3,4,5][np.array([1]).item()]    
Out[10]: 2
In [11]: np.array([1,2,3,4,5])[np.array([1])]
Out[11]: array([2])
Run Code Online (Sandbox Code Playgroud)

基本的 python 列表索引比 numpy 的更严格:

In [12]: [1,2,3,4,5][[1]]
....
TypeError: list indices must be integers or slices, not list
Run Code Online (Sandbox Code Playgroud)

编辑

再看

indices = np.random.choice(range(len(X_train)), replace=False, size=50000, p=train_probs)
Run Code Online (Sandbox Code Playgroud)

indices是一维整数数组 - 但它肯定不是标量。它是一个包含 50000 个整数的数组。列表不能同时用多个索引建立索引,无论它们是在列表还是数组中。