如何修复NumPy的ValueError错误,针对不均匀数组形状?

1 投票
3 回答
54 浏览
提问于 2025-04-11 23:55

在这段代码中,我想随机选择一个变量,要么是theta,要么是mu,让其中一个变成零。当一个变量是零的时候,另一个变量需要随机生成一个值(反之亦然)。

N = 10000

random = np.arccos(np.random.uniform(-1, 1, N))
zero = 0
choices = [random, zero]
theta = np.random.choice(choices)

if theta == random:
  mu = zero
else:
  mu = random

我知道randomzero的形状是不一样的。

这就是我遇到错误的原因:

ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.

不过,我不知道该怎么解决这个问题(我对编程还很陌生)。任何建议都很感激。

3 个回答

0

在这里其实不太适合使用 np.random.choice(),因为它没有 axis 这个参数,所以不能进行向量化处理。更好的方法是先创建一个布尔掩码(也就是一种随机变量),然后用这个掩码来决定随机值是放入 mu 变量还是 theta 变量。np.where() 就可以做到这一点。

举个例子:

random = np.arccos(np.random.uniform(-1, 1, N))
mask = np.random.uniform(size=N) < 0.5
theta = np.where(mask, random, 0)
mu = np.where(mask, 0, random)
0

你可以生成一个随机的索引来访问数组,而不是直接随机选择数组中的元素。

theta_chice = np.random.choice(2)
theta = choices[theta_chice]
mu = choices[1 - theta_chice]

注意:另一个回答提供了一种方法,可以对每一个索引独立地做随机选择。而这个回答只做了一次选择。不太确定你想要的是什么。

0

你的初始代码创建了一个数组和一个整型变量:

In [277]: random = np.arccos(np.random.uniform(-1, 1, 1000))
     ...: zero = 0
     ...: choices = [random, zero]
In [278]: random.shape
Out[278]: (1000,)

在列表上尝试使用 choices 会出现和从列表创建数组一样的错误:

In [279]: np.array(choices)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[279], line 1
----> 1 np.array(choices)

ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.

In [280]: theta = np.random.choice(choices)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[280], line 1
----> 1 theta = np.random.choice(choices)

File mtrand.pyx:920, in numpy.random.mtrand.RandomState.choice()

ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.

如果我对数组使用 choice,我会从数组中得到一个值:

In [281]: theta = np.random.choice(random)    
In [282]: theta
Out[282]: 1.3589184926442504

同样,从列表中选择一个值:

In [284]: np.random.choice([1,2,3,4])
Out[284]: 2
In [285]: type(_)
Out[285]: numpy.int32

这个选择的类型进一步说明它已经先把列表转换成了数组。

你的 if 语句也会有问题。因为 random 是一个数组,所以 == 会变成一个布尔数组。这不能在 if 表达式中使用:

In [283]: if theta == random: pass
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[283], line 1
----> 1 if theta == random: pass

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

假设你想要一个变量的数组,另一个变量为零,最好直接在 if 中使用 choice

In [290]: x = np.random.choice(2, size=10);x
Out[290]: array([1, 1, 0, 0, 0, 0, 1, 0, 1, 0])

对于单个随机的真/假值,我更喜欢使用 random 模块,但你已经用过这个变量名,所以我会继续使用 choice

In [291]: if np.random.choice(2):
     ...:     theta = random
     ...:     mu = zero
     ...: else:
     ...:     theta = zero
     ...:     mu = random
     ...:     

In [292]: theta, mu
Out[292]: 
(array([2.21440251, 0.70140386, 2.66193561, 1.52018933, 1.0636733 ,
        2.33811607, 0.98158435, 1.85139822, 0.27636737, 1.55758632,...

如果你想要一个随机的浮点数而不是整个数组,你可以修改这个 if/else

撰写回答