Adding rows/ columns to existing matrix - matlab

I have the following matrix:
a = [16 456 22 85 93;11 78 310 62 36;1 66 23 67 405];
If I wanted to add a row would it be a = [a; randi(99, 1, 5)];?
And what if I also want to add a column would it be a = [a, randi(99, 4, 1)];?
How would I add specifically between the first/second row or first/second column?

a = [16 456 22 85 93;11 78 310 62 36;1 66 23 67 405]; is a 3-by-5 matrix. So if you want to add a row you need to add a 5-digit row, i.e. a = [a; randi(99, 1, 5)]; is correct. For a column it'd be a = [a, randi(99, 3, 1)];, where I replaced your 4 with a 3 to make it act on the initial matrix. Better though would be to implicitly use sizes, so that you don't have to manually increase the number of rows/columns each time:
a = [a; randi(99,1,size(a,2))]; %// adding a row
a = [a, randi(99,size(a,1),1)]; %// adding a column
If you want to insert your new row between the first and second rows:
a = [a(1,:); randi(99,1,size(a,2)); a(2:end,:)];

Consider
a = [16 456 22 85 93;11 78 310 62 36;1 66 23 67 405];
To enter before ith row:
a = [ a(1:i-1,:) ; randi(99,1,5) ; a(i:end,:) ];
To enter before ith column:
a = [ a(:,1:i-1) , randi(99,4,1) , a(:,i:end) ];

Related

Shifting Index values in matlab

Suppose I have two rows as follows with the data
R1 = 12 13 15 17 200 23
R2 = 32 22 43 67 21 74
I would like to know how to shift the values of the 2nd index and 3rd index of R1 (e.g, 13 15) into the second row of R2 so it becomes
R2 = 32 13 15 67 21 74
It's very simple: R2(2:3) = R1(2:3);
Code sample:
R1 = [12 13 15 17 200 23];
R2 = [32 22 43 67 21 74];
R2(2:3) = R1(2:3);
You can also use the following: R2([2,3]) = R1([2,3]);, in case indexes are not sequential.
In case R1 and R2 are two rows in a matrix, you can use the following sample:
% Create the input matrix A:
R1 = [12 13 15 17 200 23];
R2 = [32 22 43 67 21 74];
A = [R1; R2];
%Copy values from index 2 and 3 of first row to index 2 and 3 of second row:
A(2, [2,3]) = A(1, [2,3]);
In case there are more rows, and you need to "shift" all down, you can use the following example:
%Create sample matrix A (6x6 elements).
A = magic(6);
%"Shift" values of index 2,3 of all rows, one row down:
A(2:end, [2,3]) = A(1:end-1, [2,3]);
Refer here: http://www.mathworks.com/company/newsletters/articles/matrix-indexing-in-matlab.html

overlapping feature values and efficient features calculation [duplicate]

If I have a matrix
F=[ 24 3 17 1;
28 31 19 1;
24 13 25 2;
47 43 39 1;
56 41 39 2];
in the first three columns I have feature values a forth column is for class labels. my problem is to get rid of same feature values when class label is different for that particular values.
like for F matrix I have to remove the rows 1,3,4 and 5 ,because for first column there are 2 different values in column four and same is for third column (39 and 39)as class label again got changed.
so output should look like
F=[28 31 19 1];
The straightforward approach would be iterating over the columns, counting the number of different classes for each value, and removing the rows for values associated to more than one class.
Example
F = [24 3 17 1; 28 31 19 1; 24 13 25 2; 47 43 39 1; 56 41 39 2];
%// Iterate over columns
for col = 1:size(F, 2) - 1
%// Count number of different classes for each value
[vals, k, idx] = unique(F(:, col));
count = arrayfun(#(x)length(unique(F(F(:, col) == x, end))), vals);
%// Remove values associated to more than one class
F(count(idx) > 1, :) = [];
end
This results in:
F =
28 31 19 1
Another take at the problem, without arrayfun (edited)
F = [24 3 17 1; 28 31 19 1; 24 13 25 2; 47 43 39 1; 56 41 39 2];
Separate both classes:
A1 = F(F(:,4)==1,1:3);
A2 = F(F(:,4)==2,1:3);
Replicate them to a 3D matrix to compare each line of class1 with each line of class2:
B2 = repmat(shiftdim(A2',-1),size(A1,1),1);
B1 = repmat(A1,[1,1,size(A2,1)]);
D4 = squeeze(sum(B1 == B2,2));
remove rows duplicated rows
A1(logical(sum(D4,2)),:) = [];
A2(logical(sum(D4,1)),:) = [];
reconstruct original matrix
R = [A1 ones(size(A1,1),1);A2 2*ones(size(A2,1),1)];

overlapping feature values values in matlab

If I have a matrix
F=[ 24 3 17 1;
28 31 19 1;
24 13 25 2;
47 43 39 1;
56 41 39 2];
in the first three columns I have feature values a forth column is for class labels. my problem is to get rid of same feature values when class label is different for that particular values.
like for F matrix I have to remove the rows 1,3,4 and 5 ,because for first column there are 2 different values in column four and same is for third column (39 and 39)as class label again got changed.
so output should look like
F=[28 31 19 1];
The straightforward approach would be iterating over the columns, counting the number of different classes for each value, and removing the rows for values associated to more than one class.
Example
F = [24 3 17 1; 28 31 19 1; 24 13 25 2; 47 43 39 1; 56 41 39 2];
%// Iterate over columns
for col = 1:size(F, 2) - 1
%// Count number of different classes for each value
[vals, k, idx] = unique(F(:, col));
count = arrayfun(#(x)length(unique(F(F(:, col) == x, end))), vals);
%// Remove values associated to more than one class
F(count(idx) > 1, :) = [];
end
This results in:
F =
28 31 19 1
Another take at the problem, without arrayfun (edited)
F = [24 3 17 1; 28 31 19 1; 24 13 25 2; 47 43 39 1; 56 41 39 2];
Separate both classes:
A1 = F(F(:,4)==1,1:3);
A2 = F(F(:,4)==2,1:3);
Replicate them to a 3D matrix to compare each line of class1 with each line of class2:
B2 = repmat(shiftdim(A2',-1),size(A1,1),1);
B1 = repmat(A1,[1,1,size(A2,1)]);
D4 = squeeze(sum(B1 == B2,2));
remove rows duplicated rows
A1(logical(sum(D4,2)),:) = [];
A2(logical(sum(D4,1)),:) = [];
reconstruct original matrix
R = [A1 ones(size(A1,1),1);A2 2*ones(size(A2,1),1)];

Remove the minimum values per each column of a Matrix

If I had a matrix A such as:
63 55 85 21 71
80 65 85 48 53
55 60 93 71 66
21 65 40 33 21
61 90 80 48 50
... and so on how would I find the minimum values of each column and remove those numbers from the matrix completely, meaning essentially I would have one less row overall.
I though about using:
[C,I] = min(A);
A(I) = [];
but that wouldn't remove the necessary numbers, and also reshape would not work either. I would like for this to work with an arbitrary number of rows and columns.
A = [
63 55 85 21 71
80 65 85 48 53
55 60 93 71 66
21 65 40 33 21
61 90 80 48 50
];
B = zeros( size(A,1)-1, size(A,2));
for i=1:size(A,2)
x = A(:,i);
maxIndex = find(x==min(x(:)),1,'first');
x(maxIndex) = [];
B(:,i) = x;
end
disp(B);
Another vectorized solution:
M = mat2cell(A,5,ones(1,size(A,2)));
z = cellfun(#RemoveMin,M);
B = cell2mat(z);
disp(B);
function x = RemoveMin(x)
minIndex = find(x==min(x(:)),1,'first');
x(minIndex) = [];
x = {x};
end
Another solution:
[~,I] = min(A);
indexes = sub2ind(size(A),I,1:size(A,2));
B = A;
B(indexes) = [];
out = reshape(B,size(A)-[1 0]);
disp(out);
Personally I prefer the first because:
For loops aren't evil - many times they are actually faster (By using JIT optimizer)
The algorithm is clearer to the developer who reads your code.
But of course, its up to you.
Your original approach works if you convert the row indices resulting from min into linear indices:
[m, n] = size(A);
[~, row] = min(A,[],1);
A(row + (0:n-1)*m) = [];
A = reshape(A, m-1, n);

MATLAB: create new matrix from existing matrix according to specifications

Assume we have the following data:
H_T = [36 66 21 65 52 67 73; 31 23 19 33 36 39 42]
P = [40 38 39 40 35 32 37]
Using MATLAB 7.0, I want to create three new matrices that have the following properties:
The matrix H (the first part in matrix H_T) will be divided to 3 intervals:
Matrix 1: the 1st interval contains the H values between 20 to 40
Matrix 2: the 2nd interval contains the H values between 40 to 60
Matrix 3: the 3rd interval contains the H values between 60 to 80
The important thing is that the corresponding T and P will also be included in their new matrices meaning that H will control the new matrices depending on the specifications defined above.
So, the resultant matrices will be:
H_T_1 = [36 21; 31 19]
P_1 = [40 39]
H_T_2 = [52; 36]
P_2 = [35]
H_T_3 = [66 65 67 73; 23 33 39 42]
P_3 = [38 40 32 37]
Actually, this is a simple example and it is easy by looking to create the new matrices depending on the specifications, BUT in my values I have thousands of numbers which makes it very difficult to do that.
Here's a quick solution
[~,bins] = histc(H_T(1,:), [20 40 60 80]);
outHT = cell(3,1);
outP = cell(3,1);
for i=1:3
idx = (bins == i);
outHT{i} = H_T(:,idx);
outP{i} = P(idx);
end
then you access the matrices as:
>> outHT{3}
ans =
66 65 67 73
23 33 39 42
>> outP{3}
ans =
38 40 32 37