"LinAlgError: 0-dimensional array given. Array must be at least two-dimensional" BUT I've know I'm passing a 2D argument

"LinAlgError: 0-dimensional array given. Array must be at least two-dimensional" BUT I've know I'm passing a 2D argument

我的第一个问题,非常感谢您提供有关如何更好地帮助我的反馈:)

在我的 Mac(Mojave,10.14.6 和 Python 版本 3.7.6.final.0)上,我遇到了上述错误。
我已经确认我的参数矩阵有 2 个维度 (8 x 8)。 我已经完成了 Traceback,并成功地在每个子函数中使用了相关的参数矩阵,但在主函数中没有使用 "monteCarlo".

顺便说一句,这是 Marcos López de Prado 的代码 "A ROBUST ESTIMATOR OF THE EFFICIENT FRONTIER" 我对过时的代码 (2.*) 和其他代码进行了一些修改,以帮助确保我正在使用我期望的矩阵。

非常非常感谢那些关心并敢于通读所有内容的勇敢者。

错误消息下方是从 Jupyter Notebook 中截取的一些代码和结果。


> 
LinAlgError                               Traceback (most recent call last)
<ipython-input-313-a5db76f0dc0a> in <module>
----> 1 monteCarlo(mu0=hist_ann_px_chg, cov0 = CovMatrix, nObs = NumObs, nSims=500, bWidth=.25, minVarPortf = False, shrink=False)
> 
<ipython-input-308-b7fbaf4dca14> in monteCarlo(mu0, cov0, nObs, nSims, bWidth, minVarPortf, shrink)
      5         mu1,cov1=simCovMu(mu0,cov0,nObs,shrink)
      6         if minVarPortf:mu1=None
----> 7         if bWidth>0:cov1=deNoiseCov(cov1,nObs*1./cov1.shape[1],bWidth)
      8         w1.loc[i]=optPort(cov1,mu1).values.flatten()
      9         w1_d.loc[i]=optPort_nco(cov1,mu1,int(cov1.shape[0]/2)).values.flatten()
> 
<ipython-input-306-062b76320e88> in deNoiseCov(cov0, q, bWidth)
     35 def deNoiseCov(cov0,q,bWidth):
     36     corr0=cov2corr(cov0)
---> 37     eVal0,eVec0=getPCA(corr0)
     38     eMax0,var0=findMaxEval(np.diag(eVal0),q,bWidth)
     39     nFacts0=eVal0.shape[0]-np.diag(eVal0)[::-1].searchsorted(eMax0)
> 
<ipython-input-306-062b76320e88> in getPCA(matrix)
     16 def getPCA(matrix):
     17 # Get eVal,eVec from a Hermitian matrix
---> 18     eVal,eVec=np.linalg.eigh(matrix)
     19     indices=eVal.argsort()[::-1] # arguments for sorting eVal desc
     20     eVal,eVec=eVal[indices],eVec[:,indices]
> 
<__array_function__ internals> in eigh(*args, **kwargs)
> 
~/opt/anaconda3/lib/python3.7/site-packages/numpy/linalg/linalg.py in eigh(a, UPLO)
   1432 
   1433     a, wrap = _makearray(a)
-> 1434     _assert_stacked_2d(a)
   1435     _assert_stacked_square(a)
   1436     t, result_t = _commonType(a)
> 
~/opt/anaconda3/lib/python3.7/site-packages/numpy/linalg/linalg.py in _assert_stacked_2d(*arrays)
    205         if a.ndim < 2:
    206             raise LinAlgError('%d-dimensional array given. Array must be '
--> 207                     'at least two-dimensional' % a.ndim)
    208 
    209 def _assert_stacked_square(*arrays):
> 
LinAlgError: 0-dimensional array given. Array must be at least two-dimensional

下面是我用这条语句调用时抛出错误的函数:

monteCarlo(mu0=hist_ann_px_chg, cov0 = CovMatrix, nObs = NumObs, nSims=500, bWidth=.25, minVarPortf = False, shrink=False)

import pandas as pd
from scipy import stats
from pandas_datareader import data as pdr
from pandas.util.testing import assert_frame_equal
import yfinance as yf


yf.pdr_override() # <== that's all it takes :-)

# download dataframe
hist_data = pdr.get_data_yahoo("^GSPC ^VIX ^DJI ^IXIC ^FTSE ^GDAXI ^STOXX50E ^N225", start="2015-01-01", end="2020-01-1")
hist_data = hist_data.iloc[:,0:8]
hist_dly_px_chg = hist_data.pct_change()


NumObs = hist_dly_px_chg.shape[0]
CovMatrix = hist_dly_px_chg.cov()
print(type(CovMatrix)) # data.frame

CovMatrix = np.matrix(CovMatrix) # matrix (8 x 8)
print(type(CovMatrix))
print(CovMatrix.shape)
print(CovMatrix.ndim)
hist_ann_px_chg = hist_dly_px_chg.mean()
print(hist_ann_px_chg*NumObs)

当我调用这个函数时:

print(np.linalg.eigh(CovMatrix))

我得到了我期望的输出,所以我不知道断开连接的位置:


(array([9.76607795e-07, 9.09734518e-06, 1.06092016e-05, 2.18149708e-05,
   7.30351257e-05, 1.16439127e-04, 2.39270121e-04, 7.82633431e-03]), matrix([[-4.82280240e-01, -4.58375572e-01, -5.31172874e-01,
      3.50650316e-02, -4.92673400e-01, -9.94286171e-02,
      1.25967021e-01,  7.37740277e-02],
    [-2.33051153e-02,  3.95717701e-02,  7.84798502e-02,
      8.95759250e-01,  1.02359842e-01, -1.47818043e-01,
      3.93700956e-01,  4.49340838e-02],
    [ 2.54965439e-02, -5.36050910e-01,  4.44240943e-01,
     -3.24298395e-01,  1.74936958e-01, -2.59428034e-01,
      5.54982822e-01,  5.97336351e-02],
    [ 8.28138825e-01, -8.35526265e-02, -1.54346913e-01,
      2.26457229e-02, -5.01976954e-01, -1.04165506e-01,
      1.19382708e-01,  7.60638006e-02],
    [-2.83219910e-01,  4.59584143e-01,  5.09453905e-01,
     -8.28536548e-02, -6.32657429e-01, -1.32770810e-01,
      1.28593449e-01,  8.79835438e-02],
    [ 1.06886068e-03, -7.82137852e-03,  1.94908915e-02,
     -2.38832357e-02, -9.03973958e-02,  9.05732488e-01,
      4.12218925e-01,  2.32359154e-02],
    [-1.33763053e-02,  5.31709637e-01, -4.80196149e-01,
     -2.88561906e-01,  2.10778168e-01, -2.24495845e-01,
      5.52334217e-01,  5.78853425e-02],
    [ 2.25154661e-03,  6.27599544e-04, -3.43348735e-03,
      6.49094855e-04, -1.06569389e-01, -4.16245867e-02,
      1.23854342e-01, -9.85673773e-01]]))

那么我应该相信谁,你还是电脑?

让我们看看错误。最底层 a 是问题数组。向上追溯,我们看到它是传递给 getPCAcorr0 数组:getPCA(corr0)

corr0=cov2corr(cov0) 创建,其中 cov0 是传递给 deNoiseCov(cov1,...)

cov1
mu1,cov1=simCovMu(mu0,cov0,nObs,shrink)

我不知道 cov2corrsimCovMu 是做什么的。但是由于 deNoiseCov 似乎是你的代码,我假设你可以在那里放一些诊断打印,检查形状和 dtype。

由于此代码来自 PY2,因此请注意,许多 py2 列表创建器是 py3 中的生成器。 np.array(range(3)) 仍然有效,但许多其他情况将创建标量 (0d) 数组(例如 map)。

np.matrix 的用法也很旧;它不再非常有用 - 但它仍然有效(所以可能不是错误的原因)。

在我的例子中,我必须将稀疏矩阵转换为密集矩阵。