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

如何用Numpy实现无循环的行间成对相似度计算

用Numpy无循环计算矩阵行之间的相似度

当然可以!用Numpy的向量化操作完全能替代循环来计算n×m矩阵每行之间的相似度,而且效率比Python循环高得多。我给你拆解两种常用的实现方式,都是纯Numpy操作,不用写任何for循环:

一、余弦相似度实现(最常用的相似度指标)

余弦相似度衡量的是两个向量方向的相似性,公式为:对于行向量a和b,相似度 = (a·b) / (||a|| * ||b||),其中a·b是点积,||a||是向量的L2范数。

用Numpy实现的步骤:

  • 计算每行的L2范数,用keepdims=True保持维度,方便后续广播运算
  • 用矩阵乘法计算所有行对的点积
  • 结合范数矩阵得到最终的相似度矩阵

示例代码:

import numpy as np

# 构造一个3×3的示例矩阵(n=3行,m=3列)
X = np.array([[1, 2, 3],
              [4, 5, 6],
              [7, 8, 9]])

# 步骤1:计算每行的L2范数,结果形状为(3,1)
row_norms = np.linalg.norm(X, axis=1, keepdims=True)

# 步骤2+3:计算余弦相似度矩阵,结果形状为(3,3)
cosine_similarity = (X @ X.T) / (row_norms @ row_norms.T)

print("余弦相似度矩阵:")
print(cosine_similarity)

输出的矩阵中,cosine_similarity[i,j]就是第i行和第j行的相似度,对角线元素为1(自己和自己完全相似)。

二、欧氏距离转相似度的实现

如果习惯用欧氏距离来衡量相似性,可以把距离转化为相似度(值越大表示越相似),比如用1/(1+欧氏距离)的方式。

用Numpy广播实现的步骤:

  • 利用广播将矩阵扩展为(n,n,m)的形状,计算每行对的元素差
  • 对元素差平方后求和,得到欧氏距离的平方
  • 开平方得到欧氏距离,再转化为相似度

示例代码:

# 步骤1+2:计算所有行对的欧氏距离平方,结果形状为(3,3)
euclidean_dist_sq = np.sum((X[:, None] - X[None, :]) ** 2, axis=-1)

# 步骤3:转化为相似度
euclidean_similarity = 1 / (1 + np.sqrt(euclidean_dist_sq))

print("\n欧氏距离转相似度矩阵:")
print(euclidean_similarity)

这里X[:, None]把原矩阵变成(3,1,3),X[None, :]变成(1,3,3),相减后自动广播为(3,3,3),再对最后一维求和就得到了每行对的距离平方。

关键说明

  • 这些操作都是Numpy的向量化运算,底层由C实现,比Python循环快几个数量级,尤其是当n很大的时候
  • 你之前能处理的n×1矩阵是m=1的特例,上面的代码完全兼容这种情况,直接代入即可

内容的提问来源于stack exchange,提问作者E.K.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:55:17