如何修复NumPy的ValueError错误,针对不均匀数组形状?
在这段代码中,我想随机选择一个变量,要么是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
我知道random
和zero
的形状是不一样的。
这就是我遇到错误的原因:
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
。