2014-06-23 65 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,如果我可以的話:-) –

相關問題