You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效计算对应元素对的距离?规避scipy.cdist的冗余计算

高效计算对应元素对的距离(无冗余运算)

直接利用NumPy的向量化运算就能实现完全无冗余的高效计算,不需要循环或生成全量两两距离矩阵。以下是针对不同度量方法的实现:

1. 针对欧几里得距离(你的示例场景)

直接计算对应元素的差值平方和,再开根号,全程是向量级运算,效率拉满:

import numpy as np

vals_1 = np.array([[0,1], [1,1], [2,1]])
vals_2 = np.array([[0,1], [2,1], [4,1]])

# 计算对应元素对的欧几里得距离
distances = np.sqrt(np.sum((vals_1 - vals_2)**2, axis=1))
# 输出:array([0., 1., 2.])

2. 兼容更多常用度量方法

如果需要支持scipy.spatial.distance.cdist里的其他常见度量(比如曼哈顿、切比雪夫、余弦距离等),可以写一个轻量的映射函数,同样基于NumPy向量化实现,避免冗余计算:

def corresponding_distance(vals1, vals2, metric='euclidean'):
    diff = vals1 - vals2
    if metric == 'euclidean':
        return np.sqrt(np.sum(diff**2, axis=1))
    elif metric == 'manhattan':
        return np.sum(np.abs(diff), axis=1)
    elif metric == 'chebyshev':
        return np.max(np.abs(diff), axis=1)
    elif metric == 'cosine':
        # 余弦距离 = 1 - 余弦相似度
        norm1 = np.linalg.norm(vals1, axis=1)
        norm2 = np.linalg.norm(vals2, axis=1)
        dot_prod = np.sum(vals1 * vals2, axis=1)
        return 1 - (dot_prod / (norm1 * norm2))
    else:
        raise ValueError(f"不支持该度量方法:{metric}")

# 调用示例
distances = corresponding_distance(vals_1, vals_2, metric='euclidean')

为什么这个方案高效?

  • 没有冗余计算:只针对对应位置的元素对计算距离,不会生成n×n的全量距离矩阵(这正是cdist内存浪费的根源)
  • 完全向量化:NumPy的底层是C实现的向量运算,比Python循环快几个数量级
  • 内存占用极低:最终只生成一个长度为n的一维数组,内存消耗和输入数组的维度成正比

内容的提问来源于stack exchange,提问作者Vladimir Fokow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 23:48:23