Using unique () to restructure a vector in MATLAB

Say A- this is an array of elements of 200 elements containing 4 different lines (each of which has 50 repetitions). Bis a 200 element vector with integers.

I use [cellNos cellStartInd enumCells ] = unique(A)and get which element in Ais equal to one of the unique strings (enumCells is an array containing integers 1-4, sorting enumerations of strings).

I want to use this information to create a 4x50 matrix of values Bso that each column has values ​​for a specific unique row. In other words, I want to convert Binto the matrix, where the columns have been arranged according to each unique entry in A.

+3
source share
4 answers

Assuming that you already know how many repetitions there will be, and that all lines are repeated with equal frequency, you can do the following:

%# sort to find where the entries occur (remember: sort does stable sorting)
[~,sortIdx] = sort(enumCells);

%# preassign the output to 50-by-4 for easy linear indexing
newB = zeros(50,4);

%# fill in values from B: first the 50 ones, then the 50 2 etc
newB(:) = B(sortIdx);

%# transpose to get a 4-by-50 array
newB = newB';

Or, more compact (thanks @Rich C)

[~,sortIdx] = sort(enumCells);
newB = reshape(B(sortIdx),50,4)';
+4
source

In the general case, when you have Ndifferent lines, and each of these lines occurs a different number of times M_i, then each corresponding set of values Bwill have a different length, and you will not be able to combine the sets together into a number array. Instead, you have to store the sets in the N-element array , and you can do this using the UNIQUE and ACCUMARRAY functions :

>> A = {'a' 'b' 'b' 'c' 'a' 'a' 'a' 'c' 'd' 'b'};  %# Sample array A
>> B = 1:10;                                       %# Sample array B
>> [uniqueStrings,~,index] = unique(A)
>> associatedValues = accumarray(index(:),B,[],@(x) {x})

associatedValues = 

    [4x1 double]    %# The values 1, 5, 6, and 7
    [3x1 double]    %# The values 2, 3, and 10
    [2x1 double]    %# The values 4 and 8
    [         9]    %# The value 9

, , , :

associatedValues = [associatedValues{:}];


: ACCUMARRAY , , associatedValues , B. B ACCUMARRAY :

 associatedValues = accumarray(index(:),1:numel(B),[],@(x) {B(sort(x))});

ACCUMARRAY, :

[index,sortIndex] = sort(index);
associatedValues = accumarray(index(:),B(sortIndex),[],@(x) {x});
+3

, find. http://www.mathworks.com/help/techdoc/ref/find.html

, :

M(:,1) = B(find(enumCells==1));
M(:,2) = B(find(enumCells==2));
M(:,3) = B(find(enumCells==3));
M(:,4) = B(find(enumCells==4));

, , .

EDIT: "sort" . . :

[s perm] = sort(enumCells);
M = reshape(B(perm),50,4);
0

, , , . @gnovice.

NumStrings = numel(CellNos);
M = zeros(size(B,1)/NumStrings,NumStrings);
for i = 1:NumStrings
    M(:,i) = B(strcmp(B,CellNos{i}));
end

, , (, CellNos}, , .

0

Source: https://habr.com/ru/post/1789265/


All Articles