【问题标题】:Optimize a distance matrix calculation优化距离矩阵计算
【发布时间】:2020-09-03 07:08:17
【问题描述】:

我试图从前两个分量的傅里叶变换中计算矩阵距离。矩阵是 40k x 40k,我这样做的方式非常慢。有没有一种计算矩阵的方法是一种更高效更快的方法?

import numpy as np
from scipy.linalg import dft

#Transform the data using Fourier Transform.
ft = norm_data.dot(dft(8).transpose())/sqrt(8)

def ft_distance_calc(x,y):
    temp = np.zeros((x,y))
    for i in range(x):
        for z in range(y):
            temp[i,z] = sqrt(np.square(abs(ft[i,0:2] - ft[z,0:2])).sum())
    return temp

ft_distance = ft_distance_calc(40000,40000) 

【问题讨论】:

  • 您可能应该尝试计算整个 np.arrays,而不是特定的单元格,它会快得多。嵌套循环导致了巨大的延迟
  • @archer 不是一个好建议。您仍然可以防止循环并对选定的列进行基于数组的计算。
  • 什么是norm_data?请提供最小的例子。谢谢

标签: python numpy scipy


【解决方案1】:

你可以使用它的内置函数:

from scipy.spatial.distance import cdist
def ft_distance_calc_2(x,y):
    return cdist(ft[:x,0:2],ft[:y,0:2])

比较使用benchit

#OP's solution
def ft_distance_calc(x,y):
    temp = np.zeros((x,y))
    for i in range(x):
        for z in range(y):
            temp[i,z] = np.sqrt(np.square(abs(ft[i,0:2] - ft[z,0:2])).sum())
    return temp

#@Ehsan's solution
def ft_distance_calc_2(x,y):
    return cdist(ft[:x,0:2],ft[:y,0:2])

#@Quang's solution
def dist_cal(x,y):
    return np.sqrt(np.square(ft[:x,None, :2]-ft[None, :y, :2]).sum(-1))

ft = np.random.rand(1000,2)
in_ = {n:[n, n] for n in [10,100,1000]}

好像ft_distance_calc_2 是最快的。

【讨论】:

  • 我使用的 cdist 的问题是矩阵由复数组成,并且无法计算距离,因为 c dist 保留了用于转换的 dft 矩阵的复数分量。
  • @djj 我不确定我是否明白你的意思?你想要复杂的距离吗?如果是这样,你如何定义它?此外,在cdist 中,您可以选择定义距离函数measure。另一种方法是使用np.linalg.norm,这可能也很快。如果您向我们提供最小的数据示例和所需的输出,我们可以提供更好的帮助。谢谢
【解决方案2】:

广播怎么样

def dist_cal(x,y):
    return np.sqrt(np.square(ft[:x,None, :2]-ft[None, :y, :2]).sum(-1))

# test
a = ft_distance_calc(400,200)
b = dist_cal(400,200)

(np.abs(a-b) < 1e-6).all()
# True

【讨论】:

    猜你喜欢
    • 2018-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-14
    相关资源
    最近更新 更多