我正在尝试计算以下矩阵中的列式差异:
A =
0 NaN NaN 0.3750 NaN
NaN 0.1250 0.2500 0.3750 NaN
我想获得:
0.3750 NaN NaN
0.1250 0.1250 0.1250
我基本上采用了列式差异,跳过NaN值并将值移到左侧。
一维案例是:
A = [0 NaN 0.250 0.375 NaN 0.625];
NaN_diff(A) = [0.250 0.125 0.250];
在MATLAB中有效地执行此操作而不使用每行低效的find()查询?
答案 0 :(得分:4)
这是一个矢量化大部分操作的解决方案:
notNan = ~isnan(A);
numNN = sum(notNan,2);
shifted = NaN(size(A));
for r = 1:size(A,1)
myRow = A(r,:);
shifted(r,1:numNN(r)) = myRow(notNan(r,:));
end
nanDiff = diff(shifted,1,2);
答案 1 :(得分:2)
这是另一种矢量化解决方案:
%// Convert to cell array without NaNs
[rows, cols] = size(A);
C = cellfun(@(x)x(~isnan(x)), mat2cell(A, ones(1, rows), cols), 'Uniform', 0);
%// Compute diff for each row and pad
N = max(sum(~isnan(A), 2));
C = cellfun(@(x)[diff(x) nan(1, N - length(x))], C, 'Uniform', 0);
%// Convert back to a matrix
nandiff = vertcat(C{:});
如果您想使用零而不是NaN
值填充结果矩阵,请将nan
中的nan(1, N - length(x))
函数调用更改为zeros
。
答案 2 :(得分:0)
这是一种替代方法,它需要您遍历每一行,但仍然应该具有不错的性能并且对我来说非常直观。
B = NaN(size(A,1),size(A,2)-1)
for i = 1:size(A,1)
idx = ~isnan(A(:,i))
B(i,1:sum(idx)) = diff(A(i,idx))
end
答案 3 :(得分:0)
我知道这是一个相当古老的问题,但对于像我这样偶然发现这个页面的人来说,这是一个更简单(imho)的解决方案:
A = [0 NaN 0.250 0.375 NaN 0.625];
A(isnan(A))=[]; % identify index of NaN values and remove them from the array
B = diff(A);
答案 4 :(得分:0)
这是另一个不使用循环的简单解决方案[但假设所有值都按升序排列]:
A=[0 NaN NaN 0.3750 NaN;NaN 0.1250 0.2500 0.3750 NaN]
A(isnan(A(:,1)))=0;
B=sort(A,2);
C=diff(B,1,2)