首页 文章

高级numpy数组乘法

提问于
浏览
1

考虑三个numpy数组 . 每个numpy数组都是三维的 . 我们有数组X,数组Y和数组Z.所有这些数组都是相同的形状 . 在相同位置组合X,Y和Z的三个匹配元素给出坐标 . 我有一个函数(不是python函数,数学),它必须在这些位置向量之一上运行,并将输出放入另一个名为s的三维数组中 . 因此,如果数组的定义如下所示:

X = [[[1,2],[3,4]]        Y = [[[1,2],[3,4]]      Z = [[[1,2],[3,4]]
     [[5,6],[7,8]]]            [[5,6],[7,8]]]          [[5,6],[7,8]]]

那么要测试的要点是:

(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),(6,6,6),(7,7,7),(8,8,8)

如果函数 s 只是 a+b+c 那么结果矩阵将是:

s=[[[ 3, 6],[ 9,12]]
   [[15,18],[21,24]]]

但事实并非如此,我们有一个名为 sv 的二维numpy数组 . 在实际问题中, sv 是维度三的 vectors 列表,就像我们的位置向量一样 . 必须从每个支持向量中减去 Each 位置向量,并找到所得向量的大小,以给出每个向量的分类 . 可以用什么numpy操作来做到这一点?

1 回答

  • 1

    我们从3个组件数组开始 xyz . 我将更改示例中的值,以便它们具有唯一值:

    x = np.array([[[1,2],[3,4]],
                  [[5,6],[7,8]]])
    y = x + 10
    z = y + 10
    

    以上每个都有 (2,2,2) 的形状,但它们可以是任何 (n, m, l) . 这种形状对我们的工艺影响不大 .

    接下来我们将三个组件数组合成一个新的数组 p ,"position vector",创建一个新的维度 i 将迭代三个物理维x,y,z,

    p = np.array([x, y, z])
    

    所以 p[0]x 等等, p 具有形状 (d, n, m, l) (其中 d=3 是向量的物理维度) .

    现在我们来看看你的矢量列表 sv ,其中大概有形状 (N, d) . 让我们为 N 使用一个小数字:

    N = 4
    d = 3
    sv = np.arange(d*N).reshape(N,d) # a list of N vectors in 3d
    

    好的,上面的内容有点重复,但我想明确(并且请纠正我可能从您的问题中产生的任何误解) .

    你想要做出一些改变, diff ,你将 n*m*l 中的每个向量都放在 p 中,并从 sv 中的每个 N 向量中减去它 . 这将为您提供 N*n*m*l 向量,每个向量都有 d 个组件 . 在进行减法之前,我们需要对齐每个维度 .

    基本上我们想要 p - sv ,但我们必须确保它们的形状匹配,以便 d 轴对齐,而 n, m, lN 轴基本上只是加起来 . numpy广播的方式是采用数组的形状,并从末尾对齐它们,因此每个轴的最后一个轴是对齐的,依此类推 . 要进行广播,每个大小必须完全匹配,或者必须为空(在左侧)或 1 . 也就是说,如果你的形状是 (a, b, c)(b, c) ,你会没事的,第二个数组会重复("broadcasted") a 次,以匹配第一个数组中 (b, c) 形状 (b, c) 的不同子数组 . 您可以使用尺寸长度 1 来强制位置,因此通常两个形状的数组 (a, b, c)(a, b) 将不会对齐,因为最后一个轴不匹配,但您可以在第二个轴的末尾添加一个新的占位符轴以使其形状 (a, b, 1) 无论 c 的值是多少,都将匹配 (a, b, c) .

    我们将形状 (N, d, 1, 1, 1) 赋予 sv ,其匹配 p 的形状 (d, n, m, l) . 这可以通过以下几种方式完成:

    sv = sv.reshape(sv.shape + (1,1,1)])
    #or
    sv.shape += (1, 1, 1)
    #or
    sv = sv[..., None, None, None]
    

    然后,我们可以做到差异:

    diff = p - sv[..., None, None, None]
    

    我们在那里 diff.shape(N, d, n, m, l) . 现在我们可以将它平方并对第二个( d )维度求和以获得每个向量的范数/大小:

    m = (diff*diff).sum(1)
    

    当然会形成 (N, n, m, l) ,或者在示例中 (4, 2, 2, 2)

    所以,一起:

    import numpy as np
    
    x = np.array([[[1,2],[3,4]],
                  [[5,6],[7,8]]])
    y = x + 10
    z = y + 10
    p = np.array([x, y, z])
    print p.shape
    N = 4
    d = 3
    sv = np.arange(d*N).reshape(N,d) # a list of N vectors in 3d
    print sv.shape
    diff = p - sv[..., None, None, None]
    print diff.shape
    m = (diff*diff).sum(1)
    print m.shape
    

相关问题