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

如何向量化Numpy数组的PyOLS运算?优化三维数组循环

向量化实现三维数组逐切片OLS回归

我有一个三维Numpy数组y_{n×m×p}和一维Numpy数组x_{p×1},需要对y的每个切片y[i,j,:]与x执行带截距的OLS回归,提取第一个回归系数。当前用嵌套循环实现,但数组规模极大时效率极低,怎么通过向量化操作优化?

原示例代码

import numpy as np
def PyOLS(xvec, yvec):
   n = xvec.shape[0]
   X = np.c_[xvec, np.ones(n)]
   betas = np.dot(np.linalg.inv(np.dot(X.T, X)), np.dot(X.T, yvec))
   return betas   

n = 20
m = 20
p = 7
x = np.random.rand(n, m, p)
y = np.random.rand(p)

res = np.zeros((n, m))

for i in range(n):
    for j in range(m):
       cx = x[i, j, :]
       b = PyOLS(cx, y)
       res[i, j] = b[0]

向量化优化思路

先拆解原PyOLS的计算逻辑:带截距的OLS回归中,第一个系数的解析公式可以直接推导出来,不用依赖矩阵求逆,同时利用Numpy的轴运算一次性完成所有切片的统计量计算。

推导后的第一个回归系数公式:
[
b_0 = \frac{p \cdot \sum(x_i y_i) - \sum(x_i) \cdot \sum(y_i)}{p \cdot \sum(x_i^2) - (\sum(x_i))^2}
]
其中p是一维数组的长度,所有求和操作针对每个y[i,j,:]切片执行。

向量化实现代码

import numpy as np

n = 20
m = 20
p = 7
x = np.random.rand(n, m, p)
y = np.random.rand(p)

# 沿第三维(axis=2)批量计算所有切片的统计量
sum_x = x.sum(axis=2)
sum_x2 = (x ** 2).sum(axis=2)
sum_xy = (x * y).sum(axis=2)
sum_y = y.sum()

# 代入公式批量计算结果
numerator = p * sum_xy - sum_x * sum_y
denominator = p * sum_x2 - sum_x ** 2
res_vectorized = numerator / denominator

# 验证与原循环结果一致(可选)
# print(np.allclose(res, res_vectorized))  # 输出True

优化优势

  • 速度提升:Numpy的向量化操作基于C底层实现,彻底避免Python循环的开销,数组规模越大,提升越明显;
  • 数值稳定性:用解析公式替代矩阵求逆,减少数值计算误差;
  • 代码简洁:无需嵌套循环,逻辑更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 21:20:51