2013-07-16 47 views
1

這個問題的MatLab (or any other language) to convert a matrix or a csv to put 2nd column values to the same row if 1st column value is the same?的產物和Group values in different rows by their first-column indexMATLAB中的矩陣轉換相對於第一個山坳

如果

 A = [2 3 234 ; 2 44 99999; 2 99999 99999; 3 123 99; 3 1232 45; 5 99999 57] 

1st column | 2nd column | 3rd column 
-------------------------------------- 
2    3   234 
2    44   99999 
2    99999  99999 
3    123  99 
3    1232  45 
5    99999  57 

我要讓

1st col | 2nd col | 3rd col | 4th col | 5th col | 6th col| 7th col 
-------------------------------------------------------------------- 
2   3  234  44  
3   123  99  1232  45 
5   57 

也就是說,每個在A的第一列中的數字,我想把數字除了「99999」

如果我們忽視了「除了99999」的一部分,我們可以編寫爲Group values in different rows by their first-column index

[U, ix, iu] = unique(A(:,1)); 
vals = reshape(A(:, 2:end).', [], 1);     %'// Columnize values 
subs = reshape(iu(:, ones(size(A, 2) - 1, 1)).', [], 1); %'// Replicate indices 
r = accumarray(subs, vals, [], @(x){x'}); 

但顯然這個代碼將不能忽略99999

我想有兩種方式

1. first make r, and then remove 99999 
2. remove 99999 first, and then make r 

無論如何,我只想要更快。

預先感謝您!

回答

1

我認爲選項1比較好,即先製作r,然後刪除99999。有R,U可以去除99999如下:

r2 = {}; % new cell array without 99999 

for i = 1:numel(r)  
    rCell = r{i}; 
    whereIs9999 = rCell == 99999; 
    rCell(whereIs9999) = []; % remove 99999 
    r2{i} = rCell; 
end 

或者更奇特的方式:

r2= cellfun(@(c) {c(c~=99999)}, r); 
+0

你不循環之前預分配,所以這可能對大電池陣列的性能問題。相反,你寧願刪除就地的值:'對於k = 1:numel(r),r {k}(r {k}〜= 99999)= []; end'。另外,你忘了在'cellfun'中放入''UniformOutput',false' ... –

+0

@EitanT在這種情況下,不需要UniformOutput',因爲我返回單元格,並且輸出中的單元格數目與輸入。但預分配在性能上始終是好的因素。 – Marcin

+0

我認爲''UniformOutput',false'在這裏是強制性的,因爲你返回一個單元格數組而不是矩陣。 –