为什么距scipy.spatial.distance的cdist这么快?

时间:2018-08-01 09:41:01

标签: python euclidean-distance scipy-spatial

我想为 10060 个记录/点创建一个距离接近矩阵,其中每个记录/点都具有 23 属性,并使用欧氏距离作为度量标准。我使用嵌套的for循环编写代码来计算每个点之间的距离(导致(n(n-1))/ 2)计算)。花了很长时间(大约8分钟)。当我使用cdist时,花费的时间要少得多(仅3秒!!! )。当我查看源代码时,cdist还使用嵌套的for循环,而且它进行 n ^ 2 次计算(大于我的逻辑所做的比较次数)。 是什么让cdist更快地执行并提供正确的输出? ,请帮助我理解。预先感谢。

1 个答案:

答案 0 :(得分:1)

您在哪里阅读源代码? python code调用(如果在默认的<T>情况下一直沿用)c代码

metric='euclidean'

static NPY_INLINE int cdist_seuclidean(const double *XA, const double *XB, const double *var, double *dm, const npy_intp num_rowsA, const npy_intp num_rowsB, const npy_intp num_cols) { npy_intp i, j; for (i = 0; i < num_rowsA; ++i) { const double *u = XA + (num_cols * i); for (j = 0; j < num_rowsB; ++j, ++dm) { const double *v = XB + (num_cols * j); *dm = seuclidean_distance(var, u, v, num_cols); } } return 0; } 在哪里

seuclidean_distance

因此,它实际上是一个三重循环,但这是高度优化的C代码。 Python static NPY_INLINE double seuclidean_distance(const double *var, const double *u, const double *v, const npy_intp n) { double s = 0.0; npy_intp i; for (i = 0; i < n; ++i) { const double d = u[i] - v[i]; s += (d * d) / var[i]; } return sqrt(s); } 循环很慢,它们会占用大量开销,并且决不能与numpy数组一起使用,因为scipy / numpy可以以python的方式利用for对象中保存的基础内存数据不能。