Python 函数、广播和元素操作的矢量化评估
鉴于此 我必须解释这段代码的作用,知道它使用广播和元素操作概念执行F的矢量化计算Python 函数、广播和元素操作的矢量化评估,python,numpy,vectorization,elementwise-operations,Python,Numpy,Vectorization,Elementwise Operations,鉴于此 我必须解释这段代码的作用,知道它使用广播和元素操作概念执行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中的加法
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可以将不同大小的数组转换为相同大小的其他数组,则也可以使用不同大小的数组,这种转换称为广播),将一个1xN阶数组与另一个Nx1阶数组相减,得到包含x_j-x_1、x_j-x_2等元素的NxN阶矩阵D。最后,在最后一行计算α的倒数(这显然是一种排列),其中每个元素乘以矩阵D中每个单元格的R计算值与水平方向上的αj之和(由于参数中的轴=1)
问题:
这里没有什么意见/改进/修复建议 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.restrape(1,-1)*vals
。这是因为广播的形状已经对齐,如下图所示-
alpha : n
vals : n x n
因此,alpha
将自动扩展到2D
,其元素沿着vals
长度的第一个轴广播,然后生成元素乘法。同样,这意味着更干净的代码
通过使用asalpha.dot(vals)
(α重塑(1,-1)*vals)。sum(轴=1)
可以通过使用asalpha.dot(vals)
的矩阵乘法替换来进一步提高性能。这一步对性能的好处应该是显而易见的
因此,第二步简化为-
out = (1./alpha) * alpha.dot(vals)
这里没有什么意见/改进/修复建议
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.restrape(1,-1)*vals
。这是因为广播的形状已经对齐,如下图所示-
alpha : n
vals : n x n
因此,alpha
将自动扩展到2D
,其元素沿着vals
长度的第一个轴广播,然后生成元素乘法。同样,这意味着更干净的代码
通过使用asalpha.dot(vals)
(α重塑(1,-1)*vals)。sum(轴=1)
可以通过使用asalpha.dot(vals)
的矩阵乘法替换来进一步提高性能。这一步对性能的好处应该是显而易见的
因此,第二步简化为-
out = (1./alpha) * alpha.dot(vals)
x_pos[:,None]-x_pos
几乎肯定会更慢,因为它必须解析切片,但只能以可忽略不计的常量,而且肯定会更惯用x_pos[:,None]-x_pos
几乎肯定会更慢,因为它必须解析切片,但只能以可忽略不计的常量,而且肯定会更惯用