我有一个长信号,其中有一些 NaN 间隔。当我使用 matlab 函数
fillmissing
填充 NaN 时,仍然剩下 NaN。
signal = rand(10000, 1);
signal(500: 700) = NaN;
signalInterpolate = fillmissing(signal, "movmean", 50);
sum(isnan(signalInterpolate))
signalInterpolate = fillmissing(signal, "movmean", 100);
sum(isnan(signalInterpolate))
signalInterpolate = fillmissing(signal, "movmean", 200);
sum(isnan(signalInterpolate))
signalInterpolate = fillmissing(signal, "movmean", 202);
sum(isnan(signalInterpolate))
结果是:
ans =
152
ans =
102
ans =
2
ans =
0
我增加了窗口大小,结果中就没有 NaN 了。看来窗口大小需要大于信号中连续 NaN 的最大长度。有没有办法可以避免使用较小窗口大小的 NaN?
来自文档
使用移动窗口均值或中位数以及窗口长度窗口来填充缺失的条目。例如,F = fillmissing(A,movmethod,window)
使用窗口长度 5 通过移动均值填充数据。fillmissing(A,'movmean',5)
您已经创建了包含 201 个连续 NaN 值的示例数据。
当您使用
"movmean", 202
时,每个移动窗口中始终至少有一个非 NaN 值,因此每个移动平均窗口值都是非 NaN,并且所有 NaN 值都可以用该值覆盖。
但是,任何较小的跨度都会有每个值都是 NaN 的窗口,并且 MATLAB 无法推断您希望用什么值来填充缺失值
想象一个具有 4 个连续 NaN 的较小示例:
[1, 2, NaN, NaN, NaN, NaN, 3, 4, 5]
"movmean", 3: [1, 2, 2, NaN, NaN, 3, 3, 4, 5]
___________ <- avg of span of 3 around first NaN = [2,NaN,NaN]
____________ <- span of 3 around second NaN = [NaN,NaN,NaN]
您需要使用
fillmissing
中的其他选项之一来定义这些值应该是什么,或者您可以使用移动均值和较小的窗口重复填充(因为连续 NaN 的数量每次都会减少窗口大小) - 这会导致有点像使用 nearest
而不是 movmean
并在中间进行一些平滑处理。
signal = rand(1,1e3)*0.1 + linspace(0,1,1e3); % Create some dummy data
signal(400:600) = NaN;
signal(500:end) = signal(500:end) + 0.3; % introduce a step change during the NaNs
% repeated in-fill of missing values
while nnz(isnan(signal)) > 0
signal = fillmissing( signal, 'movmean', 25 );
end
这是与仅使用
nearest
的比较,当您“发明”更少的数据时,这会更快并且可以说更有意义