2015-11-13 33 views
0

數據集採用以下格式:輸入樣本矩陣X和輸出類向量Y,使得X中的每一行都是一個樣本,每列都對應一個要素。 Y中的每個索引對應於X中對應樣本的相應輸出類.X可以包含實數,而Y包含正整數。在MATLAB中按類交錯數據集的高效技術

我的目標是根據班級排列數據集。例如

X =  Y = 
1 8 3  2 
4 2 6  1 
7 8 9  2 
2 3 4  3 
1 4 6  1 

應當責令和交錯的

X =  Y = 
4 2 6  1 
1 8 3  2 
2 3 4  3 
1 4 6  1 
7 8 9  2 

我已經嘗試的代碼似乎需要很長的時間,因爲它是基於串行執行運行。它是以下內容。

X = csvread('X.csv'); 
Y = csvread('Y.csv'); 

n = size(unique(Y),1); 
m = size(X,1); 

for i = 1:n 
    Dataset(i).X = X(Y==i,:); 
    Dataset(i).Y = Y(Y==i); 
end 

[num, ~] = hist(Y,n); 
maxfreq = max(num); 

NewX = []; 
NewY = []; 

for j = 1:maxfreq 
    for i = 1:n 
     if(j <= size(Dataset(i).X,1)) 
     NewX = [NewX; Dataset(i).X(j,:)]; 
     NewY = [NewY; i]; 
     end 
    end 
end 

X = NewX; 
Y = NewY; 
clear NewX; 
clear NewY; 

csvwrite('OrderedX.csv', X); 
csvwrite('OrderedY.csv', Y); 

是可以並行上面的代碼?

+0

那麼存在一些最大整數Y_max?並且是1s,2s,3s等的數量......最多隻有1個? (例如,你不可能有五個1,但只有三個2?) 或者從你的代碼看起來,可能有更多的一個數字比另一個更多。 –

+0

是@MatthewGunn,可以有更多的一個數字比另一個。例如,一個隨機設置的5個1,3個2和6個3可以排列爲'[1 2 3 1 2 3 1 2 3 1 3 1 3 3]''。 –

回答

1

你調整矩陣所有這些昂貴的時間。算法的快速加速是將NewX和NewY設置爲合適的大小,並將數據複製到:

NewX = zeros(size(X)); 
NewY = zeros(size(Y)); 
k = 1; 
for j = 1:maxfreq 
    for i = 1:n 
    if(j <= size(Dataset(i).X,1)) 
     NewX(k,:) = Dataset(i).X(j,:); 
     NewY(k) = i; 
     k=k+1; 
    end 
    end 
end 
+0

哇!這確實有竅門。你的代碼解決了問題,而不是以前的一小部分!接受答案! –

1

方法#1使用cumsumdiff遵循同樣的理念爲之一this solution上市 -

function [outX,outY] = interleave_cumsum_diff(X,Y) 

Y = Y(:); 
[R,C] = find(bsxfun(@eq,Y,unique(Y).')); 

lens = accumarray(C,1); 
out = ones(1,numel(R)); 
shifts = cumsum(lens(1:end-1)); 
out(shifts+1) = 1- diff([0 ; shifts]); 
[~,idx] = sort(cumsum(out)); 
sort_idx = R(idx)'; 

outX = X(sort_idx,:); 
outY = Y(sort_idx,:); 

方法#1使用bsxfun -

function [outX,outY] = interleave_bsxfuns(X,Y) 

Y = Y(:); 
[R,C] = find(bsxfun(@eq,Y,unique(Y).')); 
lens = accumarray(C,1); 

mask = bsxfun(@le,[1:max(lens)]',lens.'); 
V = zeros(size(mask)); 
V(mask) = R; 
Vt = V.'; 
sort_idx = Vt(mask.'); 
outX = X(sort_idx,:); 
outY = Y(sort_idx,:); 

採樣運行 -

1 )輸入:

>> X 
X = 
    1  8  3 
    4  2  6 
    7  8  9 
    2  3  4 
    1  4  6 
>> Y 
Y = 
    2 
    1 
    2 
    3 
    1 

2)輸出從兩種方法:

>> [NewX,NewY] = interleave_cumsum_diff(X,Y) 
NewX = 
    4  2  6 
    1  8  3 
    2  3  4 
    1  4  6 
    7  8  9 
NewY = 
    1 
    2 
    3 
    1 
    2 
>> [NewX,NewY] = interleave_bsxfuns(X,Y) 
NewX = 
    4  2  6 
    1  8  3 
    2  3  4 
    1  4  6 
    7  8  9 
NewY = 
    1 
    2 
    3 
    1 
    2 
+0

這會產生'outX = [4 2 6; 1 8 3; 4 2 6; 7 8 9; 1 8 3]'。 – IKavanagh

+0

@IKavanagh你確定?我檢查了幾次。 – Divakar

+0

它現在似乎工作。我很抱歉。我可能有一個變化從其他干擾它的其他東西上撒謊。 – IKavanagh