【发布时间】:2021-01-18 16:05:22
【问题描述】:
我需要一种内存和时间高效的方法来计算 Python 中 1 到 10 维中大约 50000 个点之间的距离。到目前为止我尝试的方法不是很好;到目前为止,我尝试过:
-
scipy.spatial.distance.pdist计算全距离矩阵 -
scipy.spatial.KDTree.sparse_distance_matrix计算稀疏距离矩阵直至阈值
令我惊讶的是,sparse_distance_matrix 表现不佳。我使用的示例是从单元 5 维球中统一选择 5000 个点,其中pdist 在 0.113 秒内返回结果,sparse_distance_matrix 在 44.966 秒内返回结果,当我让它使用阈值 0.1 时最大距离截止。
此时,我会坚持使用pdist,但如果有 50000 个点,它将使用 2.5 x 10^9 条目的 numpy 数组,我担心它是否会使运行时过载 (?)记忆。
有没有人知道更好的方法,或者在我的实现中看到一个明显的错误?提前致谢!
这是在 Python3 中重现输出所需的内容:
import numpy as np
import math
import time
from scipy.spatial.distance import pdist
from scipy.spatial import KDTree as kdtree
# Generate a uniform sample of size N on the unit dim-dimensional sphere (which lives in dim+1 dimensions)
def sphere(N, dim):
# Get a random sample of points from the (dim+1)-dim. Gaussian.
output = np.random.multivariate_normal(mean=np.zeros(dim+1), cov=np.identity(dim+1), size=N)
# Normalize output
output = output / np.linalg.norm(output, axis=1).reshape(-1,1)
return output
# Generate a uniform sample of size N on the unit dim-dimensional ball.
def ball(N, dim):
# Populate the points on the unit sphere that is the boundary.
sphere_points = sphere(N, dim-1)
# Randomize radii of the points on the sphere using power law to get a uniform distribution on the ball.
radii = np.power(np.random.random(N), 1/dim)
output = radii.reshape(-1, 1) * sphere_points
return output
N = 5000
dim = 5
r_cutoff = 0.1
# Generate a sample to test
sample = ball(N, dim)
# Construct a KD Tree for the sample
sample_kdt = kdtree(sample)
# pdist method for distance matrix
tic = time.monotonic()
pdist(sample)
toc = time.monotonic()
print(f"Time taken from pdist = {toc-tic}")
# KD Tree method for distance matrix
tic = time.monotonic()
sample_kdt.sparse_distance_matrix(sample_kdt, r_cutoff)
toc = time.monotonic()
print(f"Time taken from the KDTree method = {toc-tic}")
【问题讨论】:
-
请提供预期的MRE。显示中间结果与预期结果的偏差。我们应该能够将您的代码块粘贴到文件中,运行它并重现您的问题。这也让我们可以在您的上下文中测试任何建议。我们如何在您未能发布的实现中“看到明显的错误”?
-
那么 1..10 个维度,即长度为 1(1 个数字)最多 10 个的向量?
-
添加了相关代码块。反对票感觉没有必要。
-
@user3184950 是的,对于大小为 N 的 d 维样本,存储样本的 numpy 数组大小为 N x d。
标签: python scipy linear-algebra distance