Skip to main content
 首页 » 编程设计

python之Numpy:数组 > 5 产生 "The truth value of an array with more than one element is ambiguous"

2025年05月04日28myhome

我知道在 numpy 中你不能简单地对数组进行条件判断,因为它不知道如何处理它们,而这个错误就是由此产生的,但在我的例子中,我的代码要简单得多。我有:

# H and _H are 3x3 arrays with hand-assigned values 
# uv1 is 3x57600 array of coordinates, hand assigned in a loop 
HH = np.dot(_H,np.linalg.inv(H)) 
new_uv = np.dot(HH,uv1) 
du = uv1[0,:] * new_uv[2,:] 
u = new_uv[0,:] - du 
u_greater_5 = u > 5 

最后一行给出了“ValueError:具有多个元素的数组的真值不明确。使用 a.any() 或 a.all()”错误。 u 的形状为 (57600,),我可以打开交互式提示,以下工作正常:

>>> a = np.array([1,2,3,4,5]) 
>>> a > 3 
array([False, False, False,  True,  True], dtype=bool) 

但是前一个 block 中的代码没有。我也试过

np.greater(u,5) 
u[u>5] = 1 

但是他们也给出同样的错误。有什么想法吗?

此外,我不知道这是否相关,但奇怪的是,尝试访问 u[0] 会给我一个具有相同 3 个值(u 中的第一个值)的 3 向量,而它应该是一个标量?考虑到它的形状是 (57600,) ?

编辑:回溯,根据要求:

Traceback (most recent call last): 
  File "ros2vid.py", line 333, in <module> 
    process_frames(bag) 
  File "ros2vid.py", line 239, in process_frames 
    u_greater_5 = u > 5 
  ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 

这是我生成 uv1 的方法:

# frame is an image loaded from a ros bag 
uv1 = [] 
im_r = frame.shape[0] 
im_c = frame.shape[1] 
for i in range(1, im_r): 
    for j in range(im_c): 
        uv1.append([j, i, 1]) 
uv1 = np.transpose(np.array(uv1)) 

H 和 _H 的值只是我手工硬编码的数字。像这样的东西:

h11 = u0 * cosphi 
h12 = -alph_u 
h13 = alph_u + u0 * (-cosphi + cz * sinphi) 
h21 = -alph_u * sinphi + v0 * cosphi 
h22 = 0 
h23 = alph_v * (sinphi + cz * cosphi) + v0 * (-cosphi + cz * sinphi) 
h31 = cosphi 
h32 = 0 
h33 = -cosphi + cz * sinphi 
H = np.array([[h11, h12, h13], [h21, h22, h23], [h31, h32, h33]]) 

上面的所有值,如 u0、cosphi、cz 等,都是简单的标量。我已经单独检查了它们,并且 _H 也被类似地分配。我检查了 H 和 _H 的形状并验证它们是 3x3。

奇怪的是,我刚试过 u == 5 并没有给我一个错误, u > 5 会。

请您参考如下方法:

我怀疑 u 是一个对象的一维数组,对象本身是长度为 3 的一维 numpy 数组。我可以重现你的行为报告如下。首先,创建一个一维对象数组(长度为 3),并用 numpy 数组填充它:

In [26]: u = np.empty(3, dtype=object) 
 
In [27]: u[:] = [np.array([1, 2, 3]), np.array([4, 5, 6]), np.array([7, 8, 9])] 

检查u的类型和属性。首先,它是一个形状为 (3,) 的 numpy 数组。

In [28]: type(u) 
Out[28]: numpy.ndarray 
 
In [29]: u.shape 
Out[29]: (3,) 

u 的第一个元素是一个长度为 3 的数组:

In [30]: u[0] 
Out[30]: array([1, 2, 3]) 

u 的dtype 是dtype('O'),这是numpy 对object 的表示数据类型。 (如果您打印 u.dtype,它将显示object。)

In [31]: u.dtype 
Out[31]: dtype('O') 

现在尝试 u > 5:

In [32]: u > 5 
--------------------------------------------------------------------------- 
ValueError                                Traceback (most recent call last) 
<ipython-input-32-7f680a2a9455> in <module>() 
----> 1 u > 5 
 
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 

u == 5 不会生成错误,但会生成警告,并返回标量 False:

In [33]: u == 5 
/Users/warren/miniconda3/bin/ipython:1: DeprecationWarning: elementwise == comparison failed; this will raise an error in the future. 
  #!/bin/bash /Users/warren/miniconda3/bin/python.app 
Out[33]: False 

要弄清楚为什么 u 是一个对象数组,您可以逆向工作,检查变量的 .shape 和 .dtype 属性用于创建 u。