2014-06-23 111 views
2

让我更详细地描述我的问题。我将来自实验的大量数据记录到两个数组中:counttick。这两个阵列被用来计算factor像这样:如何用下一个最接近的数字替换阵列中的NaN?

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

什么是*最有意义的*号码替代?通常它是零。 –

+0

然而,这是真的,但是,这些数据应该是对数曲线 - 这只是计算的一个方面,不应该等于零(这个因子是标量)。我有同样的想法,但我意识到我需要尝试接近周围的有效值。 – Mlagma

+0

如果结果是NaN,那么您已经被告知结果不能用浮点数表示。因此任何近似都是错误的。 –

回答

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:使用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就是这样一个名字。

+0

这正是我所需要的。它完美的作品。谢谢。 – Mlagma

+0

@Mlagma太棒了!很高兴它对你有效! – Divakar

+0

+1我现在正在输入'interp1'方法,所以我会给你+2,如果我可以的话:-) –

相关问题