Python 函数、广播和元素操作的矢量化评估

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中的加法

鉴于此

我必须解释这段代码的作用,知道它使用广播和元素操作概念执行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可以将不同大小的数组转换为相同大小的其他数组,则也可以使用不同大小的数组,这种转换称为广播),将一个1xN阶数组与另一个Nx1阶数组相减,得到包含x_j-x_1、x_j-x_2等元素的NxN阶矩阵D。最后,在最后一行计算α的倒数(这显然是一种排列),其中每个元素乘以矩阵D中每个单元格的R计算值与水平方向上的αj之和(由于参数中的轴=1)

问题:

  • 考虑到我是Python新手,我的解释可以吗
  • 代码是否有错误?因为我看不到代码中考虑了每个和中的“j必须不同于1,2,…,n”…如果它实际上是错误的…我如何修复代码,使其执行与图中所述完全相同的操作

  • 这里没有什么意见/改进/修复建议

    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
    长度的第一个轴广播,然后生成元素乘法。同样,这意味着更干净的代码

    通过使用as
    alpha.dot(vals)
    (α重塑(1,-1)*vals)。sum(轴=1)
    可以通过使用as
    alpha.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
    长度的第一个轴广播,然后生成元素乘法。同样,这意味着更干净的代码

    通过使用as
    alpha.dot(vals)
    (α重塑(1,-1)*vals)。sum(轴=1)
    可以通过使用as
    alpha.dot(vals)
    的矩阵乘法替换
    来进一步提高性能。这一步对性能的好处应该是显而易见的

    因此,第二步简化为-

    out = (1./alpha) * alpha.dot(vals)
    

    x_pos[:,None]-x_pos
    几乎肯定会更慢,因为它必须解析切片,但只能以可忽略不计的常量,而且肯定会更惯用
    x_pos[:,None]-x_pos
    几乎肯定会更慢,因为它必须解析切片,但只能以可忽略不计的常量,而且肯定会更惯用