如何用下一个最接近的数字替换数组中的NaN?

Mla*_*gma 2 arrays performance matlab nan

让我更详细地描述我的问题.我正在将实验中的大量数据记录到两个数组中:counttick.然后使用这两个数组计算factor如下:

factor = (diff(tick)./diff(count))
Run Code Online (Sandbox Code Playgroud)

由于这是原始数据,因此无法保证生成"好"的数字.事实上,我得到的是类似的数组factor = [2, 3, 4, 5, 6, NaN, NaN, NaN, 3, 3, 4, 5, NaN, ... ].

我需要使用无法处理NaN的函数进一步操作这些数据.我想要做的是搜索NaN factor并用下一个最接近的数字替换它.

搜索阵列中的NaN值并替换它们不是问题.例如,我所要做的就是a(isnan(a)) = some value.然而,为了保持数据一致,我想替换的每个个体与不楠最接近NaN值.

我最初的想法是循环遍历数组,寻找NaN,然后​​输入另一个for循环直到找到有效数字,并用这个数字替换NaN.

这很可能会奏效,但我关注的是效率.我的数组可以是兆字节.有没有更好的方法来完成我需要的东西?

任何建设性的意见表示赞赏.

Div*_*kar 6

方法1:使用bsxfun+ abs+min

%// Input
factor = [2, 3, 4, 5, 6, NaN, NaN, NaN, 3, 3, 4, 5, NaN, 6]

%// Indices of NaNs
t1 = find(isnan(factor)); 

%// Indices of non-NaNs
t2 = find(~isnan(factor));

%// Get index for each NaN index that is closest, with a tie-case 
%// (closest non-NaN number being at equal distance on either side) 
%// selecting the left one
[~,ind1] = min(abs(bsxfun(@minus,t1,t2'))); %//'

%// Replace NaNs with the closest non-NaNs
factor(t1) = factor(t2(ind1))
Run Code Online (Sandbox Code Playgroud)

输出(在代码运行时)

factor =
     2     3     4     5     6   NaN   NaN   NaN     3     3     4     5   NaN     6
factor =
     2     3     4     5     6     6     6     3     3     3     4     5     5     6
Run Code Online (Sandbox Code Playgroud)

方法2:使用"最近"选项进行1-D插值

%// Input
factor = [2, 3, 4, 5, 6, NaN, NaN, NaN, 3, 3, 4, 5, NaN, 6]

%// Index array for factor
x = 1:numel(factor);

%// Indices of NaNs
t2 = find(~isnan(factor)); 

%// Replace NaNs with the closest non-NaNs
factor = interp1(x(t2),factor(t2),x,'nearest')
Run Code Online (Sandbox Code Playgroud)

输出(在代码运行时)

factor =
     2     3     4     5     6   NaN   NaN   NaN     3     3     4     5   NaN     6
factor =
     2     3     4     5     6     6     3     3     3     3     4     5     6     6
Run Code Online (Sandbox Code Playgroud)

请注意,如果出现平局(如前所述),它会选择正确的一个而不是前一个方法中的左侧一个.还要注意的是,如果第一个和最后一个元素这种做法只会工作factor都没有NaNs.

最后,建议尽量避免使用与内置MATLAB函数名相同的变量名.在这种情况下,factor就是这样一个名字.