Create group identifier from two vectors in matlab - matlab

I would like to create a unique group identifier vector (G) based on the values in two column vectors (A and B).
A = [1; 1; 1; 2; 2; 1; 1; 2; 2]
B = [1; 1; 2; 1; 2; 1; 1; 1; 2]
I would like G to look like this:
G = [1; 1; 2; 3; 4; 1; 1; 3; 4]
This is probably something simple, but I just can't seem to find the command(s) to do this.

Simple indeed. You need to use unique(...'rows') on vertically stacked input vectors and the third output from it would be your desired output, like so -
[~,~,G] = unique([A(:) B(:)],'rows')

Related

Combine 2 matrices

There is:
a = [1;2;3;4;5;6;7;8;9;10]; %(10x1 double)
b = [1;3;4;5;6;9]; %(6x1 double)
I hope to combine a and b. So my expected result is:
I think may be use conditional or first import zeros(10 2)? Could you help me?
Method 1: Conditional Checking
Checks if the values in the arrays match before filling the combined array. If they match both columns are filled. If they do not match the "NaN" undefined term is placed in the array. The variable Index that controls the scanning for array b is only incremented upon finding a match between both arrays.
%Method 1: Conditional%
a = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10];
b = [1; 3; 4; 5; 6; 9];
%Creating a result array of the same length as array "a"%
Combined_Array = zeros(length(a),2);
%Copying the first column into the result array "Combined_Array"%
for Row = 1: +1: length(a)
Combined_Array(Row,1) = a(Row,1);
end
%Padding the array "b" with zeroes to match the length of array "a"%
b = [b; zeros(length(a) - length(b),1)];
Index = 1;
for Row = 1: +1: length(a)
%If the values in arrays "a" and "b" do not match%
if a(Row,1) ~= b(Index,1)
Combined_Array(Row,2) = "NaN";
Index = Index - 1;
end
%If the values in arrays "a" and "b" match%
if a(Row,1) == b(Index,1)
Combined_Array(Row,2) = b(Index,1);
end
Index = Index + 1;
end
%Printing the result%
Combined_Array
Method 2: Concatenation and Filling Arrays
Fill in the arrays where the undefined term "NaN" is expected and concatenate the rest of the content accordingly. Using horzcat will concatenate columns together side by side. (vertcat concantates rows on top of one another)
%Method 2: Hard-Coded and Concatenation%
a = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10];
b = [1; 3; 4; 5; 6; 9];
b = [b(1); "NaN"; b(2:5);"NaN"; "NaN"; b(6); "NaN"];
Combined_Array = horzcat(a,b);

How to extract field based on field value

%Input structure
s.a=[1; 2; 1; 3; 4; 1; 2]
s.b=[4; 9; 7; 1; 0; 3; 8]
% output required
s.a=[1; 1; 1]
s.b=[4; 7; 3]
The actual structure contains many fields of long size. How to extract corresponding field values, when condition is put for field 'a' (when a==1).
Try this and adapt to the other fields:
s.b(s.a==1)
To do it for all fields in s except a and collect the results in a struct t you can use a loop:
t = struct()
fn = fieldnames(s);
for k=1:numel(fn)
t.(fn{k}) = s.(fn{k})(s.a==1);
end

removing missing elements from a vector

I have a vector B=[1; 2; 1; 2; 3; 5; 6; 8; 9; 10]
where the elements a=[4 7] are missing.
I would like to map B to a "continuous" vector like
B_map=[1; 2; 1; 2; 3; 4; 5; 6; 7; 8]
removing the "missing" elements (4 7) and "scaling" the rest accordingly..
my problem is that depending on the number of missing elemenst (in this case 2) I have to scale the vector B of different amounts...
I think I figured it out...
a = sort(a);
B_map = B;
for i = 1:numel(a)
clear id_sub
id_sub = find(B >= a(i));
B_map(id_sub) = B_map(id_sub)-1;
end

How to do a pairwise interchange of rows in Matlab?

I have a sequence in an matrix (computed from sortrows function in Matlab). Say the matrix looks something like this after computing:
A = [5; 3; 4; 1; 2];
[b, c] = size(A)
In lieu of performing permutations on the sequence in A, I would like to peform a pairwise interchange of the cells, so the performance runs better, even though the results won't be exact (it will be very close to answer though). I want the rows to look somewhat like this in the end =>
A1 = [5; 4; 3; 2; 1];
A2 = [4; 5; 3; 1; 2];
A3 = [4; 3; 5; 2; 1];
A4 = [3; 4; 5; 1; 2];
Now, the catch is that the matrix will contain as little or as much elements (it will vary). Matrix 'A' is just an example. How do I perform [b-1] pairwise interchanges on A (or any other matrix)?
A = [5; 3; 4; 1; 2];
swapIndexLeft = [1,2,3,4,5];
swapIndexRight = [2,3,4,5,1];
%// make sure the dimension of indices agree
assert(numel(swapIndexLeft) == numel(swapIndexRight))
%// ... and values do not exceed dimensions of the vector A
assert(max(swapIndexLeft)<=numel(A) )
assert(max(swapIndexRight)<=numel(A) )
%// swap iteratively
for ii = 1:numel(swapIndexLeft)
temp = A( swapIndexLeft(ii) );
A( swapIndexLeft(ii) ) = A( swapIndexRight(ii) );
A( swapIndexRight(ii) ) = temp;
%// now you have an array where the element swapIndexLeft(ii)
%// has been swapped with swapIndexRight(ii)
%// do your calculations here
end

Create a matrix using elements of other vectors in matlab

I have two vectors a, b
a=[1; 2; 3; 4]
b=[1; 2; 3]
And I want to create a matrix which will look like this
c=[1 1; 2 1; 3 1; 4 1; 1 2; 2 2; 3 2; 4 2; 1 3; 2 3; 3 3; 4 3]
Here is yet another way!
c = [repmat(a,numel(b),1),sort(repmat(b,numel(a),1))]
I have a feeling that there is a much better way, still...
p1 = repmat(a,[numel(b),1]);
p2 = imresize(b,[numel(a)*numel(b) 1],'nearest');
answer = [p1 p2];
Found a better way:
[A,B] = meshgrid(a,b);
answer = [reshape(B,[],1) reshape(A,[],1)];
Chris Taylor suggests a more compact way:
[A B]=meshgrid(a,b); [B(:) A(:)];