python - NumPy ndarray 广播 - 形状 (X,) vs (X, 1) 与 (X,Y) 一起操作

标签 python numpy multidimensional-array array-broadcasting

我有一个 NumPy ndarray,其形状为 (32, 1024) 并包含 32 个信号测量值,我想将它们组合成一个 1024 元素长的数组,每个元素的权重不同32. 我使用的是 numpy.average,但我的权重很复杂,average 根据总和对权重进行归一化,这会影响我的结果。

查看平均值代码后,我意识到我可以通过将权重乘以信号数组然后在第一个轴上求和来完成同样的事情。但是,当我尝试将 (32,) 权重数组乘以 (32, 1024) 信号数组时,我得到维度不匹配,因为 (32,) 无法广播到 (32, 1024)。如果我将权重数组 reshape 为 (32, 1),那么一切都会按预期工作,但这会导致代码相当难看:

avg = (weights.reshape((32, 1)) * data).sum(axis=0)

谁能解释为什么 NumPy 不允许我的 (32,) 数组广播到 (32, 1024) 和/或建议一种替代的、更简洁的方法来执行加权平均?

最佳答案

(X,) 之间对齐的通用设置和 (X,Y)异形数组

关于为什么的问题(32,)无法广播到 (32, 1024) ,这是因为形状没有正确对齐。将其放入示意图中,我们有:

weights :         32
data    :  32 x 1024 

我们需要对齐唯一的轴,即 weights 的第一个轴与 data 的第一轴对齐.所以,正如您发现的,一种方法是 reshape2D ,这样我们最终会得到一个单独的维度作为第二个轴。这可以通过引入一个带有 None/np.newaxis 的新轴来实现。 : weights[:,np.newaxis]weights[:,None]或简单的 reshape :weights.reshape(-1,1) .因此,回到原理图,我们将使用修改后的版本:

weights[:,None] :  32 x    1
data            :  32 x 1024

现在,形状已对齐,我们可以在这两者之间执行任何通用的元素操作,结果示意图如下所示 -

weights[:,None] :  32 x    1
data            :  32 x 1024
result          :  32 x 1024

这将广播 weights相关的逐元素操作将使用 data 执行导致 result .

解决我们的具体案例和备选方案

根据上一节的讨论,要解决我们的逐元素乘法的情况,它将是 weights[:,None]*data然后沿着axis=0求和, 即 -

(weights[:,None]*data).sum(axis=0)

让我们寻找简洁的替代品!

一种简洁且可能直观的方法是使用 np.einsum -

np.einsum('i,ij->j',weights,data)

另一种方法是使用 np.dot 进行矩阵乘法, 因为我们失去了 weights 的第一个轴针对 data 的第一轴, 像这样 -

weights.dot(data)

关于python - NumPy ndarray 广播 - 形状 (X,) vs (X, 1) 与 (X,Y) 一起操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39254755/

相关文章:

c++ - 可视化多维数组如何放置在内存中的方法?

python - 事件任务是 Spark UI 中的负数

python - 如何舍入与 networkx 图中的边标签对应的值?

JavaScript - 我想将两条信息分配给一个数组 - 我是否使用多维数组?

python - 通过最近邻平铺对 numpy 数组进行上采样的快速方法

python - 有没有 `ufunc`只是转发数据?

php - 在 php 中搜索关联数组

python - 从 IPython 运行 Flask 引发 SystemExit

python - Numpy 数组整数/ float 除法

python - 如何删除文件夹中低像素值的图片