Reorder Table Rows and columns Matlab - matlab

I have a 5x5 table:
a b c d e
a 1 2 3 4 5
b 3 5 7 2 6
c 1 3 4 6 1
d 4 4 1 7 8
e 6 7 2 1 6
where the headers are the strings.
I want to know how to reorder the table rows and columns using the headers
so for example of I wanted them to be in this order e b c a d then this will be the table:
e b c a d
e 6 7 2 6 1
b 6 5 7 3 2
c 1 3 4 1 6
a 5 7 3 1 4
d 8 4 1 4 7

Let the table be defined as
T = table;
T.a = [1 3 1 4 6].';
T.b = [2 5 3 4 7].';
T.c = [3 7 4 1 2].';
T.d = [4 2 6 7 1].';
T.e = [5 6 1 8 6].';
And let the new desired order be
order = {'e' 'b' 'c' 'a' 'd'};
The table can be reordered using just indexing:
[~, ind] = ismember(order, T.Properties.VariableNames);
T_reordered = T(ind,order);
Note that:
To reorder only columns you'd use T_reorderedCols = T(:,order);
To reorder only rows you'd use T_reorderedRows = T(ind,:);
So in this example,
T =
a b c d e
_ _ _ _ _
1 2 3 4 5
3 5 7 2 6
1 3 4 6 1
4 4 1 7 8
6 7 2 1 6
T_reordered =
e b c a d
_ _ _ _ _
6 7 2 6 1
6 5 7 3 2
1 3 4 1 6
5 2 3 1 4
8 4 1 4 7

Here is a way to do it using indexing. You can indeed re-arrange the rows and columns using indices as you would for any array. In this case, I substitute each letter in the headers array with a number (originally [1 2 3 4 5]) and then, using a vector defining the new order [5 2 3 1 4], re-order the table. You could make some kind of lookup table to automate this when you deal with larger tables:
clc
clear
a = [1 2 3 4 5;
3 5 7 2 6;
1 3 4 6 1;
4 4 1 7 8;
6 7 2 1 6];
headers = {'a' 'b' 'c' 'd' 'e'};
%// Original order. Not used but useful to understand the idea... I think :)
OriginalOrder = 1:5;
%// New order
NewOrder = [5 2 3 1 4];
%// Create table
t = table(a(:,1),a(:,2),a(:,3),a(:,4),a(:,5),'RowNames',headers,'VariableNames',headers)
As a less cumbersome alternative to manually creating the table with the function table, you can use (thanks to #excaza) the function array2table which saves a couple steps:
t = array2table(a,'RowNames',headers,'VariableNames',headers)
Either way, re-arrange the table using the new indices:
New_t = t(NewOrder,NewOrder)
Output:
t =
a b c d e
_ _ _ _ _
a 1 2 3 4 5
b 3 5 7 2 6
c 1 3 4 6 1
d 4 4 1 7 8
e 6 7 2 1 6
New_t =
e b c a d
_ _ _ _ _
e 6 7 2 6 1
b 6 5 7 3 2
c 1 3 4 1 6
a 5 2 3 1 4
d 8 4 1 4 7

Related

How to duplicate elements of a matrix without using the repmat function

Given the matrix I = [1,2;3,4], I would like to duplicate the elements to create a matrix I2 such that:
I2 = [1 1 1 2 2 2
1 1 1 2 2 2
1 1 1 2 2 2
3 3 3 4 4 4
3 3 3 4 4 4
3 3 3 4 4 4]
Other than using repmat, what other methods or functions are available?
Use kron:
>> N = 3 %// Number of times to replicate a number in each dimension
>> I = [1,2;3,4];
>> kron(I, ones(N))
ans =
1 1 1 2 2 2
1 1 1 2 2 2
1 1 1 2 2 2
3 3 3 4 4 4
3 3 3 4 4 4
3 3 3 4 4 4
This probably deserves some explanation in case you're not aware of what kron does. kron stands for the Kronecker Tensor Product. kron between two matrices A of size m x n and B of size p x q creates an output matrix of size mp x nq such that:
Therefore, for each coefficient in A, we take this value, multiply it with every value in the matrix B and we position these matrices in the same order as we see in A. As such, if we let A = I, and B be the 3 x 3 matrix full of ones, you thus get the above result.
Using indexing:
I = [1, 2; 3, 4]; %// original matrix
n = 3; %// repetition factor
I2 = I(ceil(1/n:1/n:size(I,1)), ceil(1/n:1/n:size(I,2))); %// result
One-liner with bsxfun -
R = 3; %// Number of replications
I2 = reshape(bsxfun(#plus,permute(I,[3 1 4 2]),zeros(R,1,R)),R*size(I,1),[])
Sample run -
I =
3 2 5
9 8 9
I2 =
3 3 3 2 2 2 5 5 5
3 3 3 2 2 2 5 5 5
3 3 3 2 2 2 5 5 5
9 9 9 8 8 8 9 9 9
9 9 9 8 8 8 9 9 9
9 9 9 8 8 8 9 9 9

Find how many times a pair of values occurs

Suppose there are 2 vectors (i,j), A(10,1), B(10,1) which have obtain random values from [1,10] interval. eg.
A = [1 6 1 10 1 7 1 9 3 6]
B = [7 2 3 5 6 8 7 9 10 2].
I am interested in creating a new vector which will count how many values with the same i index occur. e.g.
1 and 7 ⇒ 2 occurrences
6 and 2 ⇒ 2 occurrences
1 and 3 ⇒ 1 occurrence
10 and 5 ⇒ 1 occurrence
1 and 6 ⇒ 1 occurrence
...
etc.
So that a final array/vector C occurs, with all the possible pairs and their counted occurrence with size C(number_of_pairs,2).
Use accumarray and then find:
A = [1 6 1 10 1 7 1 9 3 6];
B = [7 2 3 5 6 8 7 9 10 2]; %// data
aa = accumarray([A(:) B(:)], 1); %// how many times each pair occurs
[ii jj vv] = find(aa);
C = [ii jj vv]; %// only pairs which occurr at least once
In your example, this gives
C =
6 2 2
1 3 1
10 5 1
1 6 1
1 7 2
7 8 1
9 9 1
3 10 1
Or perhaps aa or vv are what you need; I'm not sure about what your desired output is.
Another possible approach, inspired by #Rody's answer:
mat = [A(:) B(:)];
[bb ii jj] = unique(mat, 'rows');
C = [mat(ii,:) accumarray(jj,1)];
Something like this?
A = [1 6 1 10 1 7 1 9 3 6];
B = [7 2 3 5 6 8 7 9 10 2];
%// Find the unique pairs
AB = [A;B].';
ABu = unique(AB, 'rows');
%// Count the number of occurrences of each unique pair
%// (pretty sure there's a better way to do this...)
C = arrayfun(#(ii) ...
[ABu(ii,:) sum(all(bsxfun(#eq, AB, ABu(ii,:)),2))], 1:size(ABu,1), ...
'UniformOutput', false);
C = cat(1,C{:});
Result:
C =
1 3 1
1 6 1
1 7 2
3 10 1
6 2 2
7 8 1
9 9 1
10 5 1
Something like this?
C = zeros(10);
for k = 1:10
C(A(k), B(k)) = C(A(k), B(k)) + 1
end

Find the maximum value from the each set

I have 3 sets of data as shown in below:
A=[3 1 4 2;7 9 8 3;7 5 3 6;4 1 9 3]
B=[1 0 4 5;7 7 1 3;4 7 6 5;2 2 1 9]
C=[9 1 3 7;9 6 5 5;1 4 3 2;0 3 2 1]
I need to find out the maximum value when comparing with each other.
for instance, for matrix [1x1] from each set,
A=3,B=1,C=9,thus maximum number is 9
for matrix [1x2],maximum value=1 and so on..
so the
final result =[9 1 4 7;9 9 8 5;7 7 6 6;4 3 9 9]
Any suggestion to solve this problem? Thanks!
You can use max. For the case with 3 matrices, just use
max(A, max(B, C))
If you have more than three matrices, writing those max statements can get tiring, so you would use cat before taking the maximum
max(cat(3, A, B, C, D, E), [], 3)
You could do like this:
A=[3 1 4 2;7 9 8 3;7 5 3 6;4 1 9 3];
A = reshape(A,[1,numel(A)]);
B=[1 0 4 5;7 7 1 3;4 7 6 5;2 2 1 9] ;
B = reshape(B,[1,numel(B)]);
C=[9 1 3 7;9 6 5 5;1 4 3 2;0 3 2 1];
C = reshape(C,[1,numel(C)]);
D = [A;B;C];
for ii = 1:size(D,2)
res(1,ii) = max(D(:,ii));
end
res = reshape(res,[4,4]);

How do I make sums of sumatrixes in MATLAB without cycle?

I have a large matrix (time x frequency), which I want to reduce partially. I want to sum every 1000 rows (time-samples) together keepinq the frequency information, it is kind of a segmentation.
Is there any way to do it without any cycle in MATLAB?
A smaller example:
M=[1 2 3; 2 3 4; 5 8 7; 5 6 7; 1 2 3; 1 2 4];
and I want to sum every 2 rows together so, that I get:
[3 5 7; 10 14 14; 2 4 7]
Suppose you have a matrix with N rows and M columns and you want to sum every R rows together (where N is divisible by R),
>> mat = [1 2 3; 2 3 4; 5 8 7; 5 6 7; 1 2 3; 1 2 4]
mat =
1 2 3
2 3 4
5 8 7
5 6 7
1 2 3
1 2 4
>> [N, M] = size(mat); %=> [6, 3]
>> R = 2;
The following will allow you to sum groups of R rows:
>> res = reshape(mat, R, [])
res =
1 5 1 2 8 2 3 7 3
2 5 1 3 6 2 4 7 4
>> res = sum(res)
res =
3 10 2 5 14 4 7 14 7
>> res = reshape(res, [], M)
res =
3 5 7
10 14 14
2 4 7
You can also do everything in one line:
>> reshape(sum(reshape(mat, R, [])), [], M)
ans =
3 5 7
10 14 14
2 4 7

How to sum matrix which had been already rearranged

I have some matrix :
A = [ 1 2 3 4 5 6;
1 2 3 4 5 6]
B = [ 6 5 4 3 2 1;
6 5 4 3 2 1]
C = [ 1 2 3 4 5 6;
1 2 3 4 5 6]
what is code to make this following matrix:
Result = [1 2 9 9 10 11 5 5 5 6;
1 2 9 9 10 11 5 5 5 6]
Note : Actually the above matrix is sum of 3 matrix above which had been already rearranged like as the following matrix. #sum is sum which is based on column.
1 2 3 4 5 6
1 2 3 4 5 6
6 5 4 3 2 1
6 5 4 3 2 1
1 2 3 4 5 6
1 2 3 4 5 6
And. I sum first row by first row, and second row by second row.
To do what you say above:
Result = zeros(size(A) + [0,4]);
Result(:,1:size(A,2)) = A;
Result(:,3:end-2) = Result(:,3:end-2) + B;
Result(:,5:end) = Result(:, 5:end) + C;
The point is, you can select a subregion of a matrix, and assign another matrix to it. You just have to make sure both sides of the assignment are the same shape.