将混合 empty/non-empty 单元格转换为数字矩阵

Converting mixed empty/non-empty cells into a numeric matrix

我正在编写代码来提取我的 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) 的维度低于 nIndices。自然地,当我尝试在指定 (:,i) 和 nIndices 维度的循环中导出估计时,matlab 报告维度不匹配。我想告诉 Matlab 将 NaN 替换为 0,而不是将此位置留空,以便它能够从 AA_ARCH 生成 (1,nIndices) 矩阵。

我想到了这样的事情:

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

但我无法将这部分与之前的代码结合起来。

如果有任何提示,我将非常高兴!

最好的,卡罗琳

更新:

这是我的代码的完全可运行版本,它会产生我的问题。请注意,代码会产生维度不匹配错误,因为在时间序列 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; 

关于代码,我有一些一般性的话要说,但首先要解决您的问题:

您可以在循环中放置一个简单的 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(又名编辑器右上角的彩色方块 window)是你的朋友 - 不要忽略它:)