去趋势化 3-d 数组时忽略 NaN

Ignore NaN when detrending 3-d array

我使用的是 Matlab 2016a;我正在尝试沿第三个维度去除三维数组的趋势,但其中存在缺失值。值保持在数组中的相同位置是至关重要的,因为该位置与地理位置相关。

在此图中,假设第 2 页在随机位置有 NaN,但第 1 页和第 3 页有完整的数据。沿第 3 维去趋势化,一些向量将具有三个数据点,而一些将具有两个。我需要能够使用所有可用值来消除三维趋势。如果我要查看去除趋势后的第 1 页或第 3 页的值,应该没有缺失值(因为总是有 2 或 3 个数据点要使用),但第 2 页的位置会有 NaN 占位符找到了 NaN。

我的问题是:如何在忽略 NaN 的同时沿着三维方向去除趋势?

我尝试使用 detrend3(在 Matlab 文件交换中找到:https://www.mathworks.com/matlabcentral/fileexchange/61328-detrend3?focused=7203929&tab=function),它在对没有缺失值的 3-d 数组进行去趋势化处理时非常有效。

在存在 NaN 的情况下去趋势化会产生错误。我试过忽略 NaN 并将 NaN 设置为 -9999 然后忽略该数字,但无法使这些努力发挥作用。

任何关于前进方向的指导将不胜感激。

function detrended = detrendNaN3(A,t)
%DETRENDNAN3 Detrends a matrix with NaNs into the third dimension
%   Input Arguments:
%       - A: NxMxK matrix
%       - t: 1xK time vector

% time to same format as A
t = bsxfun(@times,permute(t,[3 1 2]),ones(size(A)));
% where A == Nan, -> t = NaN
t(isnan(A)) = NaN;
%mean of time each pixel
xm = nanmean(t,3);
% mean of every pixel in A
ym = nanmean(A,3);
% calculate slope using least squares for every pixel
a = nansum(bsxfun(@times,bsxfun(@minus,t,xm),bsxfun(@minus,A,ym)),3)./nansum(bsxfun(@minus,t,xm).^2,3);
% calculate intercept for every pixel
b = ym - a.*xm;
% calculate trend for every pixel
trend = bsxfun(@plus,b,bsxfun(@times,a,t));
% remove trend
detrended = A-trend;
end

即使该函数是完全矢量化的,它也可以写得更快一些 - 但它目前非常可读,并且使用 2500x1700x100 矩阵需要大约 8 秒,我认为这是可以接受的。

维护更新版本at the file exchange.