Python Numpy:array>5生成“具有多个元素的数组的真值不明确”

Python Numpy:array>5生成“具有多个元素的数组的真值不明确”,python,numpy,Python,Numpy,我知道,在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) d

我知道,在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)
但是上一个块中的代码没有。我也试过了

np.greater(u,5)
u[u>5] = 1
但他们也给出了同样的错误。有什么想法吗

另外,我不知道这是否相关,但奇怪的是,试图访问u[0]会给我一个3个相同值的3向量,u中的第一个值,而它应该是一个标量?考虑到它的形状是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()
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会给我一个错误。

我用随机变量重新创建了你的代码。但它在这里工作得很好:

import numpy as np
H = np.random.rand(3,3)*10
_H = np.random.rand(3,3)*10
uv1 = np.random.rand(3,57600)*10
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

我不知道这是否取决于H,_H和uv1的值。你能复制粘贴我的代码并验证你是否有问题。

我用随机变量重新创建了你的代码。但它在这里工作得很好:

import numpy as np
H = np.random.rand(3,3)*10
_H = np.random.rand(3,3)*10
uv1 = np.random.rand(3,57600)*10
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
我不知道这是否取决于H,_H和uv1的值。你能复制粘贴我的代码并验证你的代码是否有问题。

我怀疑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对对象数据类型的表示。如果打印u.D类型,它将显示对象

现在尝试u>5:

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

我怀疑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对对象数据类型的表示。如果打印u.D类型,它将显示对象

现在尝试u>5:


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

可以发布完整的回溯吗。没有进一步的追踪。这在我从main调用的函数中。我将更新帖子,但不幸的是,它没有任何启发性的内容。你能检查typeu吗?什么是u.dtype?你能发布完整的回溯吗。没有进一步的追踪。这在我从main调用的函数中。我会更新这篇文章,但不幸的是它没有任何启发性的东西。你能检查一下typeu吗?什么是u.dtype?是的,我可以确认这是有效的,正如我所怀疑的。那么问题的原因可能是什么?另外,您是否可以发布u[0]的输出?它会三次返回一个值还是一个相同值的3向量?u.shape给我57600,你应该验证你的H、_H和uv1变量的值。我更新了OP以了解如何分配uv1。对于您的代码片段,我在查找u[0]时得到一个标量,但在我的代码中,我在查找u[0]时得到一个[scalar,scalar,scalar],它们都是相同的值。是的,我可以确认这是有效的,正如我所怀疑的。那么问题的原因可能是什么?另外,您是否可以发布u[0]的输出?它会三次返回一个值还是一个相同值的3向量?u.shape给我57600,你应该验证你的H、_H和uv1变量的值。我更新了OP以了解如何分配uv1。在您的代码片段中,我在查找u[0]时得到一个标量,但在我的代码中,我在查找u[0]时得到一个[scalar,scalar,scalar],它们都是相同的值。实际上,u的数据类型是object,因此在这两者之间的某个地方,我必须将值错误地分配给u。令人惊讶的是,它对某些操作仍然非常正常,但对布尔检查不起作用。有没有一种方法可以在不遍历python循环中的数组的情况下解决这个问题?我追求的是效率。是的,对象数据类型设置了一个障碍
r到多个数组操作。有些人喜欢加法“渗透”,有些人不喜欢。我不知道测试的一般策略是什么,最简单的修复方法是确保u不是对象数组。要做到这一点,你必须弄清楚它是如何变成一个对象数组的。令人惊讶的是,它对某些操作仍然非常正常,但对布尔检查不起作用。有没有一种方法可以在不遍历python循环中的数组的情况下解决这个问题?我追求的是效率。是的,对象数据类型对许多数组操作造成了障碍。有些人喜欢加法“渗透”,有些人不喜欢。我不知道测试的一般策略是什么,最简单的修复方法是确保u不是对象数组。要做到这一点,您必须了解它最终如何成为一个对象数组。