matlab - 满足特定条件时用 NaN 或 Inf 替换值

标签 matlab multidimensional-array replace vectorization nan

我创建了以下三维模型矩阵:

mockup(:,:,1) = ...
    [100, 100, 100; ...
    103, 95, 100; ...
    101, 85, 100; ...
    96, 90, 102; ...
    91, 89, 99; ...
    97, 91, 97; ...
    105, 83, 100];

mockup(:,:,2) = ...
    [50, NaN, NaN; ...
    47, NaN, 40; ...
    45, 60, 45; ...
    47, 65, 45; ...
    51, 70, 45; ...
    54, 65, 50; ...
    62, 80, 55];

我还定义了 percentTickerAvailable = 0.5

因此,这些列代表三种不同 Assets 的股票价格。为了进一步处理,我需要按以下方式操作 NaN 值。

  1. 如果任何给定行中 NaN 的百分比大于 1 - percentTickerAvailable,则将这些特定行中的所有值替换为 NaN。也就是说,如果没有足够的 Assets 在该特定行中有价格,则完全忽略该行。
  2. 如果任何给定 ROW 中 NaN 的百分比小于或等于 1 - percentTickerAvailable,则将相应的 NaN 替换为 -inf

明确地说,“任何给定行中 NaN 的百分比”计算如下: 任何给定行中的 NaN 数除以列数。

调整后的模型矩阵应该是这样的:

mockupAdj(:,:,1) = ...
    [100, 100, 100; ...
    103, 95, 100; ...
    101, 85, 100; ...
    96, 90, 102; ...
    91, 89, 99; ...
    97, 91, 97; ...
    105, 83, 100];

mockupAdj(:,:,2) = ...
    [NaN, NaN, NaN; ...
    47, -inf, 40; ...
    45, 60, 45; ...
    47, 65, 45; ...
    51, 70, 45; ...
    54, 65, 50; ...
    62, 80, 55];

到目前为止,我做了以下事情:

function vout = ranking(vin, percentTickerAvailable)

percentNonNaN = 1 - sum(isnan(vin), 2) / size(vin, 2);
NaNIdx = percentNonNaN < percentTickerAvailable;
infIdx = percentNonNaN > percentTickerAvailable & ...
    percentNonNaN < 1;
[~, ~, numDimVin] = size(vin);

for i = 1 : numDimVin
    vin(NaNIdx(:,:,i) == 1, :, i) = NaN;
end

about = vin;

end % EoF

通过调用 mockupAdj = ranking(mockup, 0.5) 这已经将 mockup(1,:,2) 中的第一行正确地转换为 {'NaN ', 'NaN', 'NaN'}.但是,我正在为第二点而苦苦挣扎。使用 infIdx 我已经成功地识别出对应于第二个条件的行。但我不知道如何正确使用该信息以将 mockup(2,2,2) 中的单个 NaN 替换为 -inf

非常感谢任何提示。

最佳答案

这是一个可以使用矢量化解决问题的好例子。我提供了两个版本的代码,一个使用现代语法(包括隐式扩展),另一个用于旧版本的 MATLAB。

注意几点:

  • NaN 替换阶段,我使用了一个“技巧”,其中 0/0 被计算为 NaN
  • Inf 替换阶段,我使用逻辑屏蔽/索引来访问 vin 中的正确元素。

R2016b 及更新版本:

function vin = ranking (vin, percentTickerAvailable)
  % Find percentage of NaNs on each line:
  pNaN = mean(isnan(vin), 2, 'double');
  % Fills rows with NaNs:
  vin = vin + 0 ./ (1 - ( pNaN >= percentTickerAvailable));
  % Replace the rest with -Inf
  vin(isnan(vin) & pNaN < percentTickerAvailable) = -Inf;
end 

R2016b 之前:

function vin = rankingOld (vin, percentTickerAvailable)
  % Find percentage of NaNs on each line:
  pNaN = mean(isnan(vin), 2, 'double');
  % Fills rows with NaNs:
  vin = bsxfun(@plus, vin, 0 ./ (1 - ( pNaN >= percentTickerAvailable)));
  % Replace the rest with -Inf
  vin(bsxfun(@and, isnan(vin), pNaN < percentTickerAvailable)) = -Inf;
end

关于matlab - 满足特定条件时用 NaN 或 Inf 替换值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41345026/

相关文章:

python - 如何使用 Numpy 将 (1*3) 向量除以 (3*3) 矩阵? a/b 不起作用

arrays - Excel VBA 如何使用多个 Excel 区域中的值填充多维 (3d) 数组?

JAVA:我正在尝试制作基于 2D 阵列和图形的 Connect4 游戏

对于特定坐标,用另一个矩阵的值替换矩阵的一部分

正则表达式:清理 HTML

matlab - 为什么我在 MATLAB 中的数组在值 255 处饱和?

python - 将代码 matlab 转换为 python numpy

Matlab 神经网络模拟直至隐藏层

javascript - 需要帮助对特定索引中的混合字符串和整数的嵌套数组进行排序

javascript - 正则表达式替换字符串中的函数