功能,广播和元素智能操作的矢量化评估

时间:2016-09-20 06:06:23

标签: python numpy vectorization elementwise-operations

鉴于此......

enter image description here

我必须解释这段代码的作用,知道它使用广播和元素操作概念执行F的矢量化评估......

def F(x_pos, alpha):
    D = x_pos.reshape(1,-1) - x_pos.reshape(-1,1)
    return (1./alpha) * (alpha.reshape(1,-1) * R(D)).sum(axis=1)

我的解释是:

在函数的第一行中,F接收x_pos和alpha作为参数(两个numpy数组),在第二行中,矩阵D通过广播计算(基本操作,如数组numpy中的加法是按元素执行的,即逐个元素,但是如果numpy可以将它们转换为相同大小的其他大小,也可以使用不同大小的arranys,这种转换称为广播),用另一个Nx1的顺序减去1xN的数组,从而得到矩阵包含x_j - x_1,x_j - x_2等的阶NxN的D作为元素,最后,在最后一行中计算α的倒数(这显然是一种排列),其中每个元素乘以R评估的总和矩阵D的每个单元格水平乘以alpha_j(由于参数中的轴= 1)

问题:

  1. 考虑到我是Python新手,我的解释好吗?
  2. 代码有错误吗?因为我没有看到" j必须与1,2,...,n"在代码中考虑每个总和......如果它实际上是错误的......我如何修复代码,使其与图像中所述完全相同?

1 个答案:

答案 0 :(得分:0)

这里可以提出很少的意见/改进/修正。

1]第一步也可以通过引入新轴并自行减去来完成 -

D = x_pos[:,None] - x_pos

在我看来,这是一个更清洁的选择。性能优势可能只是微不足道。

2]在第二行中,我认为需要修复,因为我们需要避免R(D)的对角元素的计算。所以,如果我得到了正确的答案,更正的代码将是 -

vals = R(D)
np.fill_diagonal(vals,0)
out = (1./alpha) * (alpha.reshape(1,-1) * vals).sum(axis=1)

现在,让我们让代码更加惯用/清洁。

在该行,我们可以写:(alpha * vals)而不是alpha.reshape(1,-1) * vals。这是因为形状已经对齐broadcasting,如下面的示意图所示 -

alpha :      n
vals  :  n x n

因此,alpha将自动扩展到2D,其元素沿第一轴广播vals的长度,然后用它生成元素乘法。同样,这意味着更清晰的代码。

此处可以进一步提升绩效,(alpha.reshape(1,-1) * vals).sum(axis=1)可以matrix-multiplicatiion使用np.dot作为alpha.dot(vals)替换out = (1./alpha) * alpha.dot(vals) 。通过此步骤,性能的好处应该是显而易见的。

因此,第二步减少到 -

border-color:green;