开发者

Convert 2D matrix to 3D using two mapping vectors with categorical values in MATLAB

开发者 https://www.devze.com 2023-03-13 04:27 出处:网络
A similar question probably has been asked already, but I cannot locate it. Something wrong with me today, that I cannot find a good solution to a kind of frequent problem.

A similar question probably has been asked already, but I cannot locate it. Something wrong with me today, that I cannot find a good solution to a kind of frequent problem.

I have M x N matrix of doubles, and two N x 1 vectors (cell arrays of strings) with categorical values. The 1st vector contains K unique values and the 2nd - L unique values, such as K * L >= N.

I would like to convert the original matrix to 3D matrix M x K x L. So, to keep the 1st dimension, the 2nd dimension will correspond to unique values in the 1st vector, and 3rd dimension - to unique values in 2nd vector.

Let's consider that vectors are not sorted. It is guaranteed t开发者_开发技巧hat there are no duplicate combinations of corresponding elements in two vectors. The matrix values for missing combinations can be 0s.

I can convert categorical vectors to numbers with grp2idx, which can be considered as column and page numbers. But how to apply them to the original matrix?

EDIT:

Here is some random data:

A = reshape(1:24,4,6);
v1 = {'s1','s1','s2','s2','s3','s3'}';
v2 = {'t1','t2','t1','t2','t1','t2'}';
idx = randperm(6); %# just to randomize
v1 = v1(idx);
v2 = v2(idx);
[M, N] = size(z); %# M=4, N=6
K = numel(unique(v1)); %# K=3
L = numel(unique(v2)); %# L=2

I need to reshape matrix A to 4x3x2 in such manner that column 1 page 1 will correspond to combination s1_t1, column 2 page 2 to s2_t2, etc. In this example K*L equals N, so all the positions will have the data, but this is not a general case.


You can use accumarray for this. Note that grp2idx would give somewhat unexpected results, since it starts numbering at the first unique element it finds, instead of numbering according to sorted values of v1 or v2. If you don't care about order, you can use e.g. idx2=grp2idx(v1).

idx1 = ndgrid(1:M,1:N); %# rows
[~,idx2]=ismember(v1,unique(v1)); 
idx2 = repmat(idx2',M,1); 
[~,idx3]=ismember(v2,unique(v2));
idx3 = repmat(idx3',M,1);

out = accumarray([idx1(:),idx2(:),idx3(:)],A(:),[M,K,L],@(x)x,0);
0

精彩评论

暂无评论...
验证码 换一张
取 消