基于Numpy的多相关矩阵与权重批量矩阵乘法实现
实现批量矩阵乘法计算投资组合方差
当然可以通过调整张量的轴来实现批量矩阵乘法,不用写循环就能一步处理所有相关矩阵!下面我会一步步给你演示具体怎么做:
首先先明确我们的输入形状:
weights是(1, 2)的二维数组,代表两个资产的权重correl是(2, 2, 2)的三维张量,其中第一个轴是批量维度(对应2个不同的相关矩阵),后面两个轴是每个2x2的相关矩阵
方法1:利用广播和@运算符(最直观)
我们只需要给权重数组添加一个批量维度的占位符,让它能和correl的批量轴对齐,然后直接用矩阵乘法运算符@就能自动批量处理每个相关矩阵:
import numpy as np # 定义输入 weights = np.array([.3,.7]).reshape(1,2) correl = np.array([[[1,.4],[.4,1]],[[1,.6],[.6,1]]]) # 给权重添加批量维度,形状变为(1, 1, 2) weights_batch = weights[np.newaxis, :, :] # 给权重转置也添加批量维度,形状变为(1, 2, 1) weights_t_batch = weights.T[np.newaxis, :, :] # 一步完成批量矩阵乘法:weights @ correl[i] @ weights.T portfolio_vars = (weights_batch @ correl @ weights_t_batch).squeeze() print(portfolio_vars) # 输出:[0.676 0.748]
形状变化解释:
weights_batch(1,1,2) 和correl(2,2,2) 做矩阵乘法时,NumPy会自动把批量轴(第一个轴)广播成2,得到中间结果 (2,1,2)- 再和
weights_t_batch(1,2,1) 相乘,同样广播批量轴,最终得到 (2,1,1) 的结果 - 用
squeeze()去掉多余的维度,得到简洁的(2,)数组,对应两个相关矩阵下的投资组合方差
方法2:用np.einsum(更灵活,适合复杂轴运算)
如果你想更精确地控制每个轴的运算逻辑,可以用爱因斯坦求和符号np.einsum,代码更紧凑:
portfolio_vars = np.einsum('ij, kij, jk -> k', weights, correl, weights.T) print(portfolio_vars) # 输出同样是:[0.676 0.748]
参数解释:
'ij'对应weights的(1,2)维度'kij'对应correl的(2,2,2)维度(k是批量轴)'jk'对应weights.T的(2,1)维度'-> k'指定输出只保留批量轴k,最终得到2个结果
总结
不管用哪种方法,核心都是通过调整轴的维度,让权重数组和批量相关矩阵的维度对齐,利用NumPy的批量运算能力避免循环,一步完成所有子矩阵的乘法计算。
内容的提问来源于stack exchange,提问作者Mariano
相关产品推荐
相关产品推荐

