matlab - How can I create an array of matrices from a single matrix by using first column as index? -
suppose, have following matrix,
1 2 3 4 5 6 7 8 2 3 4 5 6 7 8 1 3 4 5 6 7 8 1 2 4 5 6 7 8 1 2 3 1 8 7 6 5 4 3 2 2 7 6 5 4 3 2 9 3 6 5 4 3 2 9 8 4 5 4 3 2 9 8 7
i want create array of 4 matrices, classified according column # 1.
for instance, output should following,
[ 2 3 4 5 6 7 8 8 7 6 5 4 3 2 3 4 5 6 7 8 1 7 6 5 4 3 2 9 4 5 6 7 8 1 2 6 5 4 3 2 9 8 5 6 7 8 1 2 3 5 4 3 2 9 8 7 ]
my target apply this parzen function each of them.
is following?
function [retval] = bayes (train, test) classcounts = rows(unique(train(:,1))); pdfmx = ones(rows(test), classcounts); variance = 0.25; pdf = parzen(train(:,2:end), test(:,2:end), variance); cl=1:classcounts clidx = train(:,1) == cl; mu(:,cl) = train(clidx,2:end); end retval = mu; endfunction
this code generating following error,
>> bayes(mat, mat) error: bayes: a(i,j,...) = x: dimensions mismatch error: called bayes @ line 11 column 12 >>
that's classic job accumarray
. outputs cell array, recommend continue 3d-matrix.
%// data = [1 2 3 4 5 6 7 8 2 3 4 5 6 7 8 1 3 4 5 6 7 8 1 2 4 5 6 7 8 1 2 3 1 8 7 6 5 4 3 2 2 7 6 5 4 3 2 9 3 6 5 4 3 2 9 8 4 5 4 3 2 9 8 7] %// input groupid = a(:,1); %// group identifier rowidx = 1:size(a,1); %// row index %// accumarray cellarray = accumarray(groupid(:),rowidx (:),[],@(x) {a(x,2:end)}) %// transform cell array 3d-matrix threedarray = cat(3,cellarray{:})
explanation
what accumarray
?
- it takes elements of
vals = rowidx
samesubs = groupid
, groups , performs action. - as want perform action on rows of matrix , not single vector, vector input required, "trick" accumarray introducing row indices input, use within function applied
a(x,2:end)
means takerowidx
samegroupid
stored inx
, use access matrixa
, put{}
around cell array output
cellarray{1} = 8 7 6 5 4 3 2 2 3 4 5 6 7 8 cellarray{2} = 7 6 5 4 3 2 9 3 4 5 6 7 8 1 cellarray{3} = 6 5 4 3 2 9 8 4 5 6 7 8 1 2 cellarray{4} = 5 4 3 2 9 8 7 5 6 7 8 1 2 3
threedarray(:,:,1) = 8 7 6 5 4 3 2 2 3 4 5 6 7 8 threedarray(:,:,2) = 7 6 5 4 3 2 9 3 4 5 6 7 8 1 threedarray(:,:,3) = 6 5 4 3 2 9 8 4 5 6 7 8 1 2 threedarray(:,:,4) = 5 4 3 2 9 8 7 5 6 7 8 1 2 3
if order of rows in output important, need "stable version" of accumarray
(inspired this answer:
%// stabilize accumarray sz = max(groupid,[],1); [~, i] = sort(groupid*cumprod([1,sz(1:end-1)]).'); %// stable accumarray cellarray = accumarray(groupid(i,:),rowidx(i),[],@(x) {a(x,2:end)})
cellarray{1} = 2 3 4 5 6 7 8 8 7 6 5 4 3 2 cellarray{2} = 3 4 5 6 7 8 1 7 6 5 4 3 2 9 cellarray{3} = 4 5 6 7 8 1 2 6 5 4 3 2 9 8 cellarray{4} = 5 6 7 8 1 2 3 5 4 3 2 9 8 7
threedarray(:,:,1) = 2 3 4 5 6 7 8 8 7 6 5 4 3 2 threedarray(:,:,2) = 3 4 5 6 7 8 1 7 6 5 4 3 2 9 threedarray(:,:,3) = 4 5 6 7 8 1 2 6 5 4 3 2 9 8 threedarray(:,:,4) = 5 6 7 8 1 2 3 5 4 3 2 9 8 7
Comments
Post a Comment