让我更详细地描述我的问题。我正在将实验中的大量数据记录到两个数组中:count
和tick
。然后使用这两个数组来计算factor
,如下所示:
factor = (diff(tick)./diff(count))
由于这是原始数据,因此无法保证生成“好”的数字。事实上,我得到的是一个类似于factor = [2, 3, 4, 5, 6, NaN, NaN, NaN, 3, 3, 4, 5, NaN, ... ]
的数组。
我需要使用无法处理NaN的函数进一步操作此数据。我想要做的是在factor
中搜索NaN并将其替换为下一个最接近的数字。
搜索阵列中的NaN值并替换它们不是问题。例如,我所要做的只是a(isnan(a)) = some value
。但是,为了保持数据的一致性,我想用最接近的非NaN值替换每个个体 NaN。
我最初的想法是循环遍历数组,寻找NaN,然后输入另一个for循环直到找到有效数字,并用这个数字替换NaN。
这很可能会奏效,但我关心的是效率。我的数组可以是兆字节。有没有更好的方法来实现我的需要?
赞赏任何有建设性的意见。
答案 0 :(得分: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))
输出(代码运行时)
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
方法2:使用最近的&#39;进行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')
输出(代码运行时)
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
请注意,如果出现平局(如前所述),它会选择正确的一个而不是前一个方法中的左侧一个。另请注意,只有factor
的第一个和最后一个元素不是NaNs
时,此方法才有效。
最后,建议尝试避免使用与内置MATLAB函数名称相同的变量名称。在这种情况下,factor
就是这样一个名字。