【问题标题】:Calculating euclidean distances with Python runs too slow用 Python 计算欧几里得距离太慢了
【发布时间】:2019-09-24 03:44:15
【问题描述】:

我将文件中的数据集读取到numpy 数组中,如下所示:

def read_data(filename):
   data = np.empty(shape=[0, 65], dtype=int)
   with open(filename) as f:
       for line in f:
           data = np.vstack((data, np.array(list(map(int, line.split(','))), dtype=int)))
   return data

我使用numpy来计算两个列表之间的欧式距离:

def euclidean_distance(x, z):
   return np.linalg.norm(x-z)

在此之后,我这样计算欧几里得距离:

for data in testing_data:
   for data2 in training_data:
       dist = euclidean_distance(data, data2)

我的问题是这段代码运行得很慢,大约需要 10 分钟才能完成。我该如何改善这一点,我缺少什么?
我必须在另一个算法中使用距离,所以速度非常重要。

【问题讨论】:

  • 当然,这里的复杂度是 O(N*M),其中 NM 分别是 testing_datatraining_data 的大小。所以,这取决于这两个数据集有多大..
  • 测试数据集由 3823 个数据和训练数据集 1797 个数据组成。所以这意味着必须计算 6.869.931 距离,我认为这并不需要 10 分钟。
  • @FogarasiNorbert 同意,这并不多!一种优化可能是摆脱手动创建list 而只使用np.fromiter(map(int, line.split(','))),尽管我认为它可能不会带来太大的改进。另一件事可能是摆脱函数euclidean_distance() 并直接内联代码,因为它只是一行。由于我们避免了 680 万次函数调用,它可能不会带来什么提升
  • @Divakar 我已经使用了cdist 以及使用numpy.linalg.norm 的手动实现,并且在速度方面没有观察到太大的差异。

标签: python performance numpy linear-algebra euclidean-distance


【解决方案1】:

您可以使用sklearn.metrics.pairwise_distances,它允许您将工作分配给所有内核。 Parallel construction of a distance matrix 讨论了相同的主题,并很好地讨论了pdistcdistpairwise_distances 的区别

如果我正确理解您的示例,您需要训练集中每个样本与测试集中每个样本之间的距离。为此,您可以使用:

dist = pairwise_distances(training_data, testing_data, n_jobs=-1)

【讨论】:

    猜你喜欢
    • 2015-07-15
    • 1970-01-01
    • 2021-01-31
    • 2015-09-23
    • 1970-01-01
    • 2019-06-11
    • 2013-04-07
    • 2020-11-29
    相关资源
    最近更新 更多