【发布时间】:2020-12-21 06:51:09
【问题描述】:
我有一个非常大的输入数据集,包含 50,000 个 9 维样本(即 50000x9 矩阵)。此数据已使用 DFT 进行转换:
dft_D = data.dot(dft(9).T) / np.sqrt(9)
我想计算每对行的欧几里得距离。当使用实数矩阵时,我发现scipy.spatial.distance.pdist 在计算欧几里得距离方面是最快的(例如,计算data 上的距离需要~`15 秒)。但是,此函数不适用于复数。
我尝试了this SO post 中提出的解决方案,但这给我带来了严重的内存问题(即“无法为形状为 (50000, 50000, 9) 且数据类型为 complex128 的数组分配 191.GiB”)。我也尝试过使用 this Medium article 中定义的 EDM,但这也给了我类似的内存问题。
最初,我能够通过使用定义np.sqrt(np.sum(np.square(np.abs(data[i,:] - data[j,:])))) 遍历行和列来计算这些欧几里得距离。这非常慢。然后我将docs 中描述的定义用于sklearn.metrics.pairwise.euclidean_distances(它也不适用于复数),它稍微快一些,但仍然很慢(运行超过2 小时)。
这是我的最终结果(注意,由于距离矩阵是对称的,所以我只计算了完整距离矩阵的一半),
import numpy as np
def calculate_euclidean_distance(arr, num_rows):
dist_matrix = np.empty(int((num_rows*(num_rows - 1))/2))
idx = 0
dot_dict = {}
# get the 0th row out of the way
dot_dict[0] = arr[0,:].dot(arr[0,:])
for i in range(1,num_rows):
# Save the value of dot(X,X) in dict to not recompute it every time when needed
if i not in dot_dict:
dot_dict[i] = arr[i,:].dot(arr[i,:])
i_dot = dot_dict[i]
for j in range(0,i):
j_dot = dot_dict[j]
dist_matrix[idx] = np.sqrt(i_dot - 2*arr[i,:].dot(arr[j,:]) + j_dot)
idx+=1
return dist_matrix
当涉及复数时,有没有更快的方法来获得这些距离?
【问题讨论】:
-
您的代码无法运行,因为未定义
norm_data和e(在dist_matrix[e]中)。 -
@mtrw 啊谢谢,这个问题已经解决了!
标签: python numpy complex-numbers euclidean-distance