【发布时间】:2021-11-30 07:27:20
【问题描述】:
我有 2 个数组:
>>> a.shape
(9, 3, 11)
>>> b.shape
(9,)
我想计算c[i, j] = f(a[i, j, :], b[i]) 的等价物,其中f(a0, b0) 是一个带有len(a0) == 11 和len(b0) == 9 两个参数的函数。这里,i 正在迭代 range(9),j 正在迭代 range(3)。
有没有办法使用numpy.vectorize 对此进行编码?还是通过一些巧妙的广播更简单?
我已经尝试了 2 个小时,但我只是不明白如何使它工作......我尝试广播或使用签名但无济于事。
【问题讨论】:
-
np.array([f(a[i,j,:], b[i]) for j in range(3)] for i in range(9)])。a + b[:,None,None]会起作用,但结果是 (9,3,11)。或者np.sum(a + b[:,None,None]).axis=2),如果你想(9,3),但你也可以先np.sum(a, axis=2)。 -
np.vectorize在默认模式下将标量值传递给函数。有一个signature选项可以让它传递数组,但使用起来更棘手,甚至更慢。apply_along_axis可以迭代a的i,j维度(缓慢),但它不能同时迭代b。它只是一个数组迭代器。嵌套列表推导式可能是您的最佳选择。 -
函数示例可能会有所帮助。您还需要明确函数返回的内容。它是标量吗,所以
c可以是数字 dtype 数组。我认为这需要对 11 号尺寸进行某种缩减。 -
@hpaulj,最后我可以找到解决方案:
np.vectorize(f, signature="(k),(1)->()")然后我必须像f(a, b[:, None, None]一样称呼它。你认为这会比循环慢得多吗?
标签: python numpy array-broadcasting numpy-ufunc