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

如何无需for循环,用Numpy实现二维数组逐行批量相减?

Numpy完全向量化实现行对全行的运算

问题背景

在Numpy中,当二维数组A(形状5000×3072)与行向量v(形状1×3072)相减时,因列数匹配,v会自动广播为与A同形状的数组完成运算。但如果要让二维数组V的每一行分别与整个A做运算,直接操作无法实现。现有一个带for循环的半向量化距离计算函数,需要改造为完全无循环的实现。

现有半向量化代码

def compute_distances_one_loop(V):
    num_test = V.shape[0]
    num_train = A.shape[0]
    dists = np.zeros((num_test, num_train))
    for i in range(num_test):   
        initial = np.sqrt(np.square(A - V[i,:]))
        dists[i,:] = initial.sum(axis=1)
    return dists

示例场景

给定以下数组:

matrix_e = np.ones((3,3)) * 6
matrix_f = np.array([[1,2,3],[4,5,6]])

如何无需for循环得到形状为(6,3)的matrix_g:

matrix_g = np.array([[5,4,3],[5,4,3],[5,4,3],[2,1,0],[2,1,0],[2,1,0]])

解决方案

1. 完全向量化的距离计算

原函数的核心是计算V的每一行与A的每一行对应元素的绝对值之和(注:np.sqrt(np.square(x))等价于np.abs(x))。利用Numpy的广播机制,通过扩展维度实现无循环运算:

def compute_distances_no_loop(V):
    # 扩展A的维度为(1, num_train, num_features)
    A_expanded = A[np.newaxis, :, :]
    # 扩展V的维度为(num_test, 1, num_features)
    V_expanded = V[:, np.newaxis, :]
    # 广播相减后计算绝对值,再沿特征维度求和
    dists = np.abs(A_expanded - V_expanded).sum(axis=2)
    return dists

扩展维度后,A_expanded与V_expanded相减会自动广播为(num_test, num_train, num_features)的数组,最后沿第三维度(特征维度)求和,直接得到num_test×num_train的距离矩阵。

2. 示例场景的无循环实现

要得到目标matrix_g,本质是让matrix_f的每一行分别与matrix_e的所有行相减,再将结果展平为6×3的数组。两种实现方式:

方式一:广播+维度重塑

# 扩展matrix_f为(2,1,3),matrix_e为(1,3,3),广播相减得到(2,3,3)
temp = matrix_e - matrix_f[:, np.newaxis, :]
# 重塑为(6,3)
matrix_g = temp.reshape(-1, 3)

方式二:重复数组+直接运算

# 将matrix_f的每一行重复3次,得到(6,3)
f_repeated = np.repeat(matrix_f, repeats=3, axis=0)
# 将matrix_e重复2次,得到(6,3)
e_repeated = np.tile(matrix_e, (2,1))
matrix_g = e_repeated - f_repeated

内容的提问来源于stack exchange,提问作者Ülke Eren Aktaş

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 23:17:12