Python NumPy ndarray广播-形状(X,)与(X,1)以(X,Y)操作
我有一个NumPyPython NumPy ndarray广播-形状(X,)与(X,1)以(X,Y)操作,python,numpy,multidimensional-array,array-broadcasting,Python,Numpy,Multidimensional Array,Array Broadcasting,我有一个NumPyndarray,它的形状是(321024),包含32个信号测量值,我想将它们组合成一个1024个元素的长数组,32个元素中的每一个都有不同的权重。我使用的是numpy.average,但我的权重很复杂,average根据结果的总和对权重进行归一化 通过查看平均值的代码,我意识到我可以通过将权重乘以信号数组,然后在第一个轴上求和来完成同样的事情。但是,当我尝试将(32,)权重数组乘以(32,1024)信号数组时,由于(32,)不能广播到(32,1024),我得到了一个维度不匹配。
ndarray
,它的形状是(321024),包含32个信号测量值,我想将它们组合成一个1024个元素的长数组,32个元素中的每一个都有不同的权重。我使用的是numpy.average
,但我的权重很复杂,average
根据结果的总和对权重进行归一化
通过查看平均值的代码,我意识到我可以通过将权重乘以信号数组,然后在第一个轴上求和来完成同样的事情。但是,当我尝试将(32,)权重数组乘以(32,1024)信号数组时,由于(32,)不能广播到(32,1024),我得到了一个维度不匹配。如果我将权重数组重塑为(32,1),那么一切都会按预期工作,但是这会导致相当难看的代码:
avg = (weights.reshape((32, 1)) * data).sum(axis=0)
有人能解释为什么NumPy不允许我的(32,)数组向(32,1024)广播和/或建议一种替代的、更简洁的加权平均方法吗?在
(X,)
和(X,Y)
形状数组之间对齐的通用设置
关于为什么(32,)
不能广播到(321024)
的问题,这是因为形状没有正确对齐。要将其放入示意图中,我们有:
weights : 32
data : 32 x 1024
我们需要将唯一的轴对齐,即权重的第一个轴
与数据的第一个轴对齐。因此,正如您所发现的,一种方法是将重塑为2D
,这样我们将以一个单体维度作为第二个轴。这可以通过引入一个新轴来实现,该轴具有:权重[:,np.newaxis]
或权重[:,无]
或简单的重塑:权重。重塑(-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.dot(data)
这将广播权重
,并使用数据
执行相关的元素操作,从而产生结果
解决我们的具体案例和备选方案
根据上一节中的讨论,要解决元素相乘的情况,将是权重[:,无]*数据
,然后沿轴=0
求和,即-
(weights[:,None]*data).sum(axis=0)
让我们来寻找合适的替代方案
一种简洁且可能直观的方法是-
另一种方法是使用矩阵乘法,因为我们失去了权重的第一个轴与数据的第一个轴,如下所示-
weights[:,None] : 32 x 1
data : 32 x 1024
result : 32 x 1024
weights.dot(data)
numpy可以将(32,)扩展到(1,32)
到(1024,32)
;但是您必须授予它将(32,)
扩展到(32,1)
的权限。这可以避免在其他情况下出现歧义,例如,将a(32,)乘以a(1024,)。在我最近的回答中有更多关于这一点的内容,清晰而彻底的回答,谢谢。我不知道np.einsum
——虽然这是一种公认的简洁方法,但我认为对于不熟悉语法的人来说,这并不明显。np.dot
样式更接近于“合理”且紧凑的东西。