【问题标题】:Override broadcasting conventions in Numpy?覆盖 Numpy 中的广播约定?
【发布时间】:2022-12-14 01:18:21
【问题描述】:

我有两个 Numpy 数组,xy,其中 x 是 n 维且 n>=1 但在“编译时”未知,而 y 是一维的。 x 的第一个维度保证匹配 y 的第一个(也是唯一)维度。我想得到他们的“总和”,称它为s,与x具有相同的维度,如下所示:

import numpy as np

x  = np.random.randn(5,100,10)
y  = np.random.randn(5)

s = np.empty_like(x)
for i in range(x.shape[0]):
   s[i] = x[i] + y[i]

但我想避免使用 for 循环,这既是为了可读性,更重要的是,出于速度原因。

显然,由于 Numpy 中的广播约定如何工作,我不能做 x+y。这要么会引发错误,要么更糟的是,会巧合地产生意外结果。

我找到了两个相对不错的衬垫,

s1 = (x.T + y).T
s2 = x + y[(slice(0, y.shape[0]),) + (np.newaxis,)*(x.ndim-1)]

这还不错。第一个是利用它确实是第一的x 中与 y 中唯一维度匹配的维度。否则它不会工作。第二个更笼统,但相当冗长。

由于我仍在学习 Python 和 Numpy 的过程中,我想知道是否有其他(理想情况下更好,但我也对一般情况感兴趣)的替代方案来做我想做的事情。基本上我可能正在寻找的是一种覆盖广播约定的方法......

【问题讨论】:

  • y 上使用reshape 可能不那么罗嗦

标签: python numpy array-broadcasting


【解决方案1】:

您无法更改广播规则。因此,无论采用何种方式,您都必须向 y 添加尾随维度。

您使用了newaxis,生成:

In [9]: y[:,None,None].shape
Out[9]: (5, 1, 1)

reshape构造一个类似的元组可能会更简单一些:

In [10]: y.reshape((-1,1,1)).shape
Out[10]: (5, 1, 1)

expand_dims 是指定reshape 的另一种方式:

In [11]: np.expand_dims(y,(1,2)).shape
Out[11]: (5, 1, 1)

这些都不是计算昂贵的,即使代码最终有点冗长。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多