2013-04-01 35 views
2

我試圖計算下面的矩陣列明智的差異:從矩陣和位移值MATLAB刪除NaN值留下

A = 
    0  NaN  NaN 0.3750  NaN 
    NaN 0.1250 0.2500 0.3750  NaN 

我想獲得:

0.3750 NaN NaN 
0.1250 0.1250 0.1250 

我在哪裏基本上取得了列差,跳過NaN值並將值移到左邊。

一維的情況將是:

A = [0 NaN 0.250 0.375 NaN 0.625]; 
NaN_diff(A) = [0.250 0.125 0.250]; 

任何方式在MATLAB有效地做到這一點,而無需使用效率低下的發現()每行查詢?

+1

這是不明確的,如果你是「跳躍的NaN」,那麼爲何仍有NaN的在您的示例輸出? –

+0

對不起,我添加了這些NaN以確保矩陣是矩形 - 具有更多數字的行將具有更長的差異。他們可以任意地爲零。 – ejang

回答

4

下面是向量化大多數操作的解決方案:

notNan = ~isnan(A); 
numNN = sum(notNan,2); 

shifted = NaN(size(A)); 

for r = 1:size(A,1) 
    myRow = A(r,:); 
    shifted(r,1:numNN(r)) = myRow(notNan(r,:)); 
end 

nanDiff = diff(shifted,1,2); 
+2

我得到了一個'Subscripted assignment dimension mismatch'錯誤。也許你在for循環中的意思是'1:numNN(r)'? –

+0

@EitanT:確實如此 – Jonas

2

這裏是另一種矢量化的解決方案:

%// Convert to cell array without NaNs 
[rows, cols] = size(A); 
C = cellfun(@(x)x(~isnan(x)), mat2cell(A, ones(1, rows), cols), 'Uniform', 0); 

%// Compute diff for each row and pad 
N = max(sum(~isnan(A), 2)); 
C = cellfun(@(x)[diff(x) nan(1, N - length(x))], C, 'Uniform', 0); 

%// Convert back to a matrix 
nandiff = vertcat(C{:}); 

如果你想墊零,而不是NaN值的結果矩陣,將nan(1, N - length(x))中的nan函數調用更改爲zeros

0

這是一種替代方法,它要求您循環遍歷每一行,但仍然應該具有不錯的性能,並且對我來說感覺非常直觀。

B = NaN(size(A,1),size(A,2)-1) 

for i = 1:size(A,1) 
    idx = ~isnan(A(:,i)) 
    B(i,1:sum(idx)) = diff(A(i,idx)) 
end 
0

我知道,這是一個相當古老的問題,但對於我這樣的人誰跌入這個頁面,這裏是一個簡單的(恕我直言)解決問題的辦法:

A = [0 NaN 0.250 0.375 NaN 0.625]; 
A(isnan(A))=[]; % identify index of NaN values and remove them from the array 
B = diff(A); 
0

這裏由於不使用循環的另一個簡單的解決方案[但假設所有的值按升序排列]:

A=[0  NaN  NaN 0.3750  NaN;NaN 0.1250 0.2500 0.3750  NaN] 
A(isnan(A(:,1)))=0; 
B=sort(A,2); 
C=diff(B,1,2)