如何向量化多元正态分布计算以提升3D点PDF求解效率?
向量化改造多元正态分布PDF计算以提升效率
你当前的迭代实现因为逐个处理每个点,没有利用Numpy的向量化广播能力,导致计算效率偏低。针对你的场景(每个点的协方差矩阵是对角矩阵且三个维度方差相同),可以大幅简化公式并实现完全向量化的计算,避免Python循环开销。
公式简化推导
由于每个点的协方差矩阵是σ²I(σ为该点的置信度,I是3x3单位矩阵),可以将多元正态PDF公式简化:
- 协方差行列式:
det(cov) = σ⁶ - 协方差逆矩阵:
inv(cov) = (1/σ²)I - 指数项:
-0.5 * (||real - guess||²) / σ² - 常数项:
1 / [(2π)^(3/2) * σ³]
最终每个点的PDF可简化为:
pdf = (1 / [(2π)^1.5 * σ³]) * exp( -0.5 * ||diff||² / σ² )
向量化Numpy实现
import numpy as np n = 10 def create_points(n): return np.random.randint(0, 1000, size=(n, 3)) real = create_points(n) guess = create_points(n) uncertainties = np.random.randint(1, 100, size=n) def vectorized_scoring_numpy(real, guess, uncertainties): # 计算所有点的差值 (n,3) diff = real - guess # 计算每个点差值的平方和 (n,) diff_sq_sum = np.sum(diff ** 2, axis=1) # 预计算置信度的平方和三次方 (n,) sigma_sq = uncertainties ** 2 sigma_cubed = uncertainties ** 3 # 计算指数部分 (n,) exponent = -0.5 * diff_sq_sum / sigma_sq # 计算常数项 (n,) const = 1 / ((2 * np.pi) ** 1.5 * sigma_cubed) # 计算每个点的PDF并求和 pdfs = const * np.exp(exponent) score = np.sum(pdfs) return score # 验证结果与原迭代方法一致 print("原Scipy迭代结果:", iterative_scoring_scipy(real, guess, uncertainties)) print("向量化Numpy结果:", vectorized_scoring_numpy(real, guess, uncertainties))
效率提升说明
- 完全避免了Python级别的循环,所有计算都通过Numpy底层的C优化实现,当
n较大(比如上万级)时,速度会比迭代版本快几十到上百倍。 - 利用Numpy的广播机制,所有数组操作都是批量进行,内存访问更高效。
内容的提问来源于stack exchange,提问作者NicolaiF
相关产品推荐
相关产品推荐

