最简单方法是用np.linalg.norm(a-b),但多维需注意axis参数:单点到多点用axis=1,两组点配对距离需广播扩展维度后用axis=2,慎防nan/inf。

直接用 np.linalg.norm 计算两向量距离最简单,但数组形状不对会报错
如果两个数组都是 1D 且长度相同(比如 a = np.array([1, 2, 3]),b = np.array([4, 5, 6])),直接写 np.linalg.norm(a - b) 就行,结果是标量。但很多人卡在多维场景:比如想算一批点对之间的距离,或一个点到多个点的距离——这时传入的数组 shape 不匹配,np.linalg.norm 会抛 ValueError: axis must be specified 或静默返回错误维度。
批量计算“一个点到多个点”的距离:指定 axis=1
常见场景:已知一个查询点 query(shape (d,))和一组候选点 points(shape (n, d)),要算 query 到每个点的欧氏距离(输出 shape (n,))。关键不是广播减法,而是 norm 的 axis 参数:
- 先做
points - query:NumPy 自动广播,结果 shape 是(n, d) - 再用
np.linalg.norm(..., axis=1):对每行(即每个点的 d 维差值)求模长 - 别用
axis=0,那会得到 d 个值(每维的 L2 范数),不是你想要的距离
示例:
import numpy as np query = np.array([1, 2]) points = np.array([[4, 6], [0, 0], [1, 2]]) distances = np.linalg.norm(points - query, axis=1) # → array([5., 2.236..., 0.])
计算两组点之间所有配对距离:避免 for 循环,用广播+keepdims
若要算 A 中每个点(shape (m, d))到 B 中每个点(shape (n, d))的距离,得到 shape (m, n) 的距离矩阵,不能直接减——维度不兼容。正确做法是扩展维度再广播:
- 把 A 变成
(m, 1, d)(加中间维度),B 变成(1, n, d) - 用
A[:, None] - B[None, :]得到(m, n, d)差值数组 - 再用
np.linalg.norm(..., axis=2)沿最后一维求范数 - 注意
None比np.expand_dims更简洁;axis=2对应原 d 维,别错写成axis=-1(虽等价但可读性差)
性能上,这比双层 Python for 快 10 倍以上,但内存占用是 O(m*n*d),大数据时容易爆内存。
为什么不用 scipy.spatial.distance.cdist?
如果你已经引入 SciPy,cdist(A, B, metric='euclidean') 更省心:自动处理维度、支持稀疏输入、有 C 底层加速。但纯 NumPy 环境下,np.linalg.norm 是唯一内置选择。另外注意:np.linalg.norm 默认计算 2-范数,无需额外参数;传 ord=2 是冗余的,还略微拖慢速度。
最容易被忽略的是:当输入含 NaN 或 inf 时,np.linalg.norm 会直接传播 NaN,不报错也不警告——务必在调用前用 np.isnan 或 np.isfinite 检查数据质量。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











