【问题标题】:Python ValueError: non-broadcastable output operand with shape () doesn't match the broadcast shape (50,)Python ValueError:具有形状()的不可广播输出操作数与广播形状(50,)不匹配
【发布时间】:2021-11-04 14:33:43
【问题描述】:

我正在使用 numpy 计算两个数组的叉积,但遇到以下错误:

ValueError: non-broadcastable output operand with shape () doesn't match the broadcast shape (50,)

我有三个变量,它们是 numpy.ndarray 类型并代表行向量:

  • n = [0 0 1]
  • beta = [array with 50 elements, 0, array with 50 elements]
  • betap = [array with 50 elements, 0, array with 50 elements]

beta 的第一个和第三个元素代表以下分段函数的结果:

t_start = (-2 * 0.01) / 299792458
t_end = (3 * 0.01) / 299792458
t = np.linspace(t_start, t_end)

x_of_t = = np.piecewise(t,
                      [np.logical_or(t < t_start, t > t_end), np.logical_and(t_start <= t, t <= t_end)],
                      [((0.01 * 0.02) / (2 * np.pi * 2)), (lambda t: (0.01 * 0.02) / (2 * np.pi * 2) * np.cos((2 * np.pi)/0.01 * 299792458 * t))])

z_of_t = np.piecewise(t, 
                      [t < t_start, t > t_end, np.logical_and(t_start <= t, t <= t_end)], 
                      [(lambda t: (np.sqrt(0.75) * 299792458 * (t - t_start) + np.sqrt(0.75) * (1 - 0.02**2 / (4 * np.sqrt(0.75) * 2**2)) * 299792458 * t_start - 0.01 * 0.02**2 / (16 * np.pi * np.sqrt(0.75) * 2**2) * np.cos(2 * ((2 * np.pi)/0.01) * 299792458 * t_start))), 
                       (lambda t: np.sqrt(0.75) * 299792458 * (t - t_end) + np.sqrt(0.75) * (1 - 0.02**2 / (4 * np.sqrt(0.75) * 2 **2)) * 299792458 * t_end - 0.01 * 0.02**2 / (16 * np.pi * np.sqrt(0.75) * 2 **2) * np.cos(2 * ((2 * np.pi)/0.01) * 299792458 * t_end)),
                       (lambda t: np.sqrt(0.75) * (1 - 0.02**2 / (4 * np.sqrt(0.75) * 2 **2)) * 299792458 * t - 0.01 * 0.02**2 / (16 * np.pi * np.sqrt(0.75) * 2**2) * np.cos(2 * ((2 * np.pi)/lambda_u) * 299792458 * t))])

betap 的第一个和第三个元素代表这些函数的导数。我正在使用 numpy 的梯度函数np.gradient(beta_x_of_t) 计算导数,因此数组长度将匹配(len = 50)。同样,在检查nbetabetap 的形状时,它们都具有相同的形状(3,)。检查betabetap 的第一个和第三个元素的形状会得到以下形状:(50,)

鉴于形状相同,我认为我应该能够使用np.cross(n-beta, betap) 执行叉积,但出现上述错误。

我的目标是双重的:

  1. 了解错误消息的含义。例如,我查看了此处发布的许多其他问题,但似乎没有人回答输出操作数不可广播意味着什么。
  2. 使用该信息解决错误以计算叉积。

【问题讨论】:

  • 如果您查看了许多其他问题,您肯定会看到 cmets 要求 traceback。你为什么不在这里提供?
  • n-betabetapshapedtype 是什么?这与np.cross 的记录期望相比如何?显示生成这些对象的清晰代码。我为x_of_t 等编码,以及对betap 等的某种令人困惑的描述,但没有明确的可复制粘贴代码。

标签: python arrays numpy array-broadcasting cross-product


【解决方案1】:

来自np.cross 文档,2 个示例数组:

In [51]: x = np.array([[1,2,3], [4,5,6]])
    ...: y = np.array([[4,5,6], [1,2,3]])
    ...: 
In [52]: np.cross(x[0],y[0])
Out[52]: array([-3,  6, -3])
In [53]: np.cross(x,y)
Out[53]: 
array([[-3,  6, -3],
       [ 3, -6,  3]])

因此,cross 采用 2 个向量叉积。所以它可以采用 (n,3) 个数组,并返回 (n,3) 个结果。 (或 (n,2) 用于 2d 矢量交叉)。

当然与自身的交叉是0

In [59]: np.cross(x,x)
Out[59]: 
array([[0, 0, 0],
       [0, 0, 0]])

让我们像你的beta一样列一个列表:

In [60]: beta = [np.arange(3),0,np.arange(3)]
In [61]: beta
Out[61]: [array([0, 1, 2]), 0, array([0, 1, 2])]

numpy 不喜欢从这样的列表中创建一个数组:

In [62]: np.array(beta)
<ipython-input-62-f4485c3a6e4c>:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
  np.array(beta)
Out[62]: array([array([0, 1, 2]), 0, array([0, 1, 2])], dtype=object)

但是让我们尝试在这样一个 (3,) 形状的数组上执行cross

In [64]: barr = np.array(beta,object)
In [65]: barr
Out[65]: array([array([0, 1, 2]), 0, array([0, 1, 2])], dtype=object)
In [66]: np.cross(barr, barr)
Traceback (most recent call last):
  File "<ipython-input-66-7218b4a081e0>", line 1, in <module>
    np.cross(barr, barr)
  File "<__array_function__ internals>", line 5, in cross
  File "/usr/local/lib/python3.8/dist-packages/numpy/core/numeric.py", line 1655, in cross
    cp0 -= tmp
ValueError: non-broadcastable output operand with shape () doesn't match the broadcast shape (3,)

这看起来像你的错误。

np.cross 旨在与 (N,3) 形状的数字 dtype 数组一起使用。像 beta 这样的对象 dtype 数组是错误的。我什至不确定你打算发生什么。

您的大部分问题都是无关紧要的,与错误无关。您的问题应该已经显示了回溯,并清楚地说明了参数的形状和数据类型。

【讨论】:

  • 感谢您的回复,但我认为您只是略过了我的问题。我确实清楚地说明了 beta、betap 和 n 的形状。我还指定 beta、betap 和 n 是 numpy.ndarray 类型,因此说 beta 是一个列表是不正确的。
  • 我认为在这种情况下形状并不重要,但重要的是 dtype。 np.cross 也应该与 (3, N) 形状的数字 dtype 数组一起使用。
  • 对象 dtype 似乎也无关紧要。将 beta 转换为列向量后,叉积可以正常执行
  • 在回答问题时,我关注traceback、数组shapedtype,以及可重复性(如果可能,使用minimal reproducible example)。通过提供np.cross (3,) 形状的对象 dtype 数组,我能够重现该错误。如果指定了 axis 参数,则具有形状 (3,N) 的数字 dtype 数组确实可以工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-09
  • 2020-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-03
  • 2020-08-03
相关资源
最近更新 更多