【问题标题】:Numpy operation for euclidean distance between multidimensional arrays多维数组之间欧式距离的 Numpy 运算
【发布时间】:2017-05-03 16:33:31
【问题描述】:

我有两个 numpy 数组。 'A' 大小为 w,h,2 和 'B' 大小为 n,2。 换句话说,A 是二维向量的二维数组,而 B 是二维向量的一维数组。 结果我想要的是一个大小为 w,h,n 的数组。最后一维是一个 n 维向量,其中每个分量是来自 A 的相应向量(由前两个维度 w 和 h 表示)与 B 的第 n 个向量之间的欧式距离。

我知道我可以在 python 中手动循环遍历 w、h 和 n 并计算每个元素的距离,但我想知道是否有一种聪明的方法可以通过 numpy 操作来提高性能。

我发现了一些类似的问题,但不幸的是,所有这些问题都使用相同维度的输入数组。

【问题讨论】:

    标签: python performance numpy multidimensional-array euclidean-distance


    【解决方案1】:

    方法#1

    您可以将 A 重塑为 2D,使用期望 2D 数组作为输入的 Scipy's cdist,获取这些欧几里德距离并最终重塑回 3D

    因此,实现将是 -

    from scipy.spatial.distance import cdist
    
    out = cdist(A.reshape(-1,2),B).reshape(w,h,-1)
    

    方法 #2

    由于缩减轴的长度仅为2,我们可以只对输入数组进行切片以节省中间数组的内存,就像这样 -

    np.sqrt((A[...,0,None] - B[:,0])**2 + (A[...,1,None] - B[:,1])**2)
    

    A[...,0,None]A[...,1,None]的解释:

    有了None,我们只是在切片A 的末尾引入了一个新轴。好吧,我们举个小例子-

    In [54]: A = np.random.randint(0,9,(4,5,2))
    
    In [55]: A[...,0].shape
    Out[55]: (4, 5)
    
    In [56]: A[...,0,None].shape
    Out[56]: (4, 5, 1)
    
    In [57]: B = np.random.randint(0,9,(3,2))
    
    In [58]: B[:,0].shape
    Out[58]: (3,)
    

    所以,我们有:

    A[...,0,None]  : 4 x 5 x 1 
    B[:,0]         :         3
    

    本质上是:

    A[...,0,None]  : 4 x 5 x 1 
    B[:,0]         : 1 x 1 x 3
    

    执行减法时,单例维度为broadcasted,对应其他参与数组的维度-

    A[...,0,None] - B  : 4 x 5 x 3
    

    我们对沿最后一个轴的第二个索引重复此操作。我们在平方和最后一个平方根之后添加这两个数组以获得最终的eucl。距离。

    【讨论】:

    • 哇。第一种方法实际上很容易。没想到!关于方法 2,我对 numpy 相当陌生,您能否详细说明切片和索引操作? [...,None,1] 这件事真的很令人困惑。
    • @MarioDekena A[...,0,None] 对于它本质上的作用看起来更直观。用几个 cmets 编辑。
    • 非常感谢!似乎我还有很多关于 numpy 的知识;)
    • @MarioDekena 只是好奇在您的用例中方法#2 与应用程序#1 相比有多快?
    • 很快就会进行一些性能测试。我会发布结果。
    猜你喜欢
    • 2017-04-21
    • 1970-01-01
    • 1970-01-01
    • 2012-11-15
    • 2017-09-08
    • 1970-01-01
    • 2012-08-01
    • 1970-01-01
    • 2015-02-25
    相关资源
    最近更新 更多