填充Numpy股票收益协方差矩阵NaN值时的维度不匹配问题排查
解决numpy维度不匹配问题:分析与修复
咱们一步一步拆解你的问题,先搞清楚为什么两行代码表现不一样,再给出修复方案。
先看第一行代码为什么能运行
你写的cov_tot[idx_miss, :] = col_mean能正常工作,核心是numpy的广播机制:
cov_tot[idx_miss, :]选中的是2行100列的子矩阵,形状是(2, 100)col_mean是你用np.nanmean(cov_tot, axis=1)计算出来的,形状是(100,)(因为axis=1求的是每行的均值,100行就得到100个值)- numpy看到要把
(100,)的数组赋值给(2,100)的矩阵时,会自动把col_mean沿着第一个维度(行维度)复制2次,变成(2,100)的形状,刚好和目标区域匹配,所以不会报错。
最后一行代码报错的原因
而cov_tot[:, idx_miss] = col_mean报错,问题也出在形状不匹配:
cov_tot[:, idx_miss]选中的是100行2列的子矩阵,形状是(100, 2)col_mean还是(100,)的一维数组- 这时候numpy尝试广播,但
(100,)和(100,2)的形状不兼容:一维数组的长度是100,对应目标矩阵的行维度,但目标矩阵的列维度是2,一维数组没有列维度,无法自动扩展成(100,2)的形状,所以抛出shape mismatch错误。
修复方案
你只需要把col_mean转换成列向量(增加一个维度,变成(100,1)的形状),这样numpy就能把它沿着列维度复制2次,匹配(100,2)的目标区域了。修改最后一行代码:
cov_tot[:, idx_miss] = col_mean[:, np.newaxis]
或者用reshape也可以:
cov_tot[:, idx_miss] = col_mean.reshape(-1, 1)
额外提醒:你的均值计算可能方向错了
你提到要“用各列的均值填充NaN”,但你当前用的是np.nanmean(cov_tot, axis=1),这个参数axis=1求的是每行的均值,而不是每列的。如果要计算每列的均值,应该把参数改成axis=0:
col_mean = np.nanmean(cov_tot, axis=0)
这样col_mean的每个值就对应原矩阵中每一列的非NaN值的均值,符合你最初的需求。
内容的提问来源于stack exchange,提问作者mHelpMe
相关产品推荐
相关产品推荐

