将混合的空/非空单元格转换为数字矩阵

时间:2015-06-14 08:52:16

标签: matlab default-value cell-array is-empty

我正在编写一个代码来提取我的AR(1)-GARCH(1)参数,我使用AR(1)-GJR(1,1)模型估计到各个矩阵,以便我可以将它们用作我计算中的变量。由于我有16个时间序列变量,我通过以下方式将代码与循环结合起来:

for i=1:nIndices
AA_ARCH(:,i) = cell2mat(fit{i}.Variance.ARCH)';
end; 

我的问题是,对于某些变量,对于AA_ARCH(:,i),no维度低于nIndices。当然,当我尝试在指定维度(:,i)和nIndices的循环中导出估计值时,matlab会报告维度不匹配。我想告诉Matlab将NaN替换为0而不是将该点留空,以便能够从AA_ARCH生成(1,nIndices)矩阵。

我想到了这样的事情:

fit{i}.Variance.Leverage(isnan(fit{i}.Variance.Leverage))=0

但我无法将此部分与之前的代码结合使用。

我会对任何提示感到高兴!

Best,Carolin

更新:

这是我的代码的完全可运行版本,它会产生我的问题。请注意,代码会产生尺寸不匹配错误,因为对于时间序列1,fit.gjr(1,1)中没有ARCH和GARCH估计值。对于这些缺失值,我希望在提取的矩阵中将0作为占位符。

returns = randn(2,750)'; 

T       = size(returns,1);
nIndices = 2; 

model     = arima('AR', NaN, 'Variance', gjr(1,1));
residuals = NaN(T, nIndices);    
variances = NaN(T, nIndices);
fit       = cell(nIndices,1);

options   = optimset('fmincon');
options   = optimset(options, 'Display'  , 'off', 'Diagnostics', 'off', ...
                              'Algorithm', 'sqp', 'TolCon'     , 1e-7);

for i = 1:nIndices
    fit{i} = estimate(model, returns(:,i), 'print', false, 'options', options);
    [residuals(:,i), variances(:,i)] = infer(fit{i}, returns(:,i));
end

for i=1:nIndices
AA_beta(:,i) = cell2mat(fit{i}.AR)';
AA_GARCH(:,i) = cell2mat(fit{i}.Variance.GARCH)';
AA_ARCH(:,i) = cell2mat(fit{i}.Variance.ARCH)';
AA_Leverage(:,i) = cell2mat(fit{i}.Variance.Leverage)';
end; 

1 个答案:

答案 0 :(得分:1)

我对代码有一些一般性的说法,但首先是解决问题的方法:

您可以在循环中放置一个简单的if / else结构来处理空数组的情况:

for ind1=1:nIndices
    AA_beta(:,ind1) = cell2mat(fit{ind1}.AR)'; %//'
    %// GARCH    
    if isempty(cell2mat(fit{ind1}.Variance.GARCH)') %//'
        AA_GARCH(1,ind1) = 0;
    else
        AA_GARCH(:,ind1) = cell2mat(fit{ind1}.Variance.GARCH)'; %//'
    end
    %// ARCH (same exact code, should probably be exported to a function)
    if isempty(cell2mat(fit{ind1}.Variance.ARCH)') %//'
        AA_ARCH(1,ind1) = 0;
    else
        AA_ARCH(:,ind1) = cell2mat(fit{ind1}.Variance.ARCH)'; %//'
    end
    AA_Leverage(:,ind1) = cell2mat(fit{ind1}.Variance.Leverage)'; %//'
end; 

旁注:我最初尝试过这样的事情:soz = @(A)isempty(A)*0+~isempty(A)*A;作为if / else的内联替换,但事实证明MATLAB没有按照我想要的方式处理[] + 0(结果在[]而不是0;与JS之类的其他语言不同。

至于我要说的其他事情:

  • 我坚决支持不应该使用ij作为循环索引的概念,因为在涉及复杂数字的某些情况下这可能会导致兼容性问题(例如,如果您循环索引为i,然后1*i现在引用循环索引而不是-1的平方根。)
  • 您的部分问题是您编写的数组未预先​​分配 - 这也意味着MATLAB在创建时不知道正确的数据类型。除了明显的性能影响之外,它还可能导致错误,就像你在这里遇到的那样。例如,如果您使用AA_beta等单元格,那么它们可能包含空值,您可以使用cellfunisempty的组合替换您心中所需的占位符。底线:lint(又名编辑窗口右上方的彩色方块)是你的朋友 - 不要忽视它:)