How to extract a row of a matrix - matlab

In every other language if I have a matrix, if I call a mono-dimensional index, the result will be an array.I don't know why in Matlab if you take a single index of a matrix, you'll get a single element, that's stupid.
Anyway in C:
mat[4][4];
mat[0] is an array.
In Matlab:
mat=[1 2; 3 4];
How do I take the first row of the matrix? mat(1) is 1, not [1 2].
EDIT: There is another problem, I have a problem with this function:
function str= split(string, del)
index=1;
found=0;
str=['' ; ''];
for i=1:length(string)
if string(i)==del
found=1;
index=1;
elseif found==1
str(2,index)=string(i);
index=index+1;
else
str(1,index)=string(i);
index=index+1;
end
end
end
This returns sometimes a matrix and sometimes an array.
For example if I use split('FF','.') I get 'FF' as result, but what if I want to return a matrix? I can't even choose the dimensione of the matrix, in this context a weak typed language is a big disvantage.

You have to say which columns you want. : stands for all indices in a dimension, so to take first row
mat(1,:)
It is not stupid, but useful. If you address a matrix with only one index, it implicitly gets converted to a vector. This gives you the option to use linear indices (see sub2ind).

This will extract the second row
vector = mat(2,:)
And This will extract the second column
vector = mat(:,2)
You can use
vector = mat(end,:)
To extract the last row
Hope this helps you

From Matrix Indexing in MATLAB:
When you index into the matrix A using only one subscript, MATLAB
treats A as if its elements were strung out in a long column vector,
by going down the columns consecutively
I just hope it doesn't look stupid to you anymore (along with the right answers from angainor and Marwan)

Related

Removing rows based on a condition (Matlab)

I am trying to remove rows from a matrix based on a condition. I have a 371000x5 double matrix, and a 371000x1 vector of dummies (1 and 0). I want to remove each row from the original matrix, where the value of the vector of dummies is 1.
I have tried the following, but it is taking very long:
for i = 1:size(matrix_num,1)
if missing_matrix(i,1) >=0
matrix_num(i,:) = [];
end
end
My Matlab has been busy for over 30 minutes now, so I am not even sure if the code is right. Is there a more efficient way to do this?
Additionally, I have to do the same action on a cell matrix (categorical data). Should I expect any huge difference from the numerical matrix?
The programmatic way of doing this is:
new_matrix = old_matrix(missing_vector==1,:)
for keeping lines with missing_vector 1
new_matrix = old_matrix(missing_vector==0,:)
for removing lines with missing_vector 1
For educational values, if you want the loop to work, don't do that row by row. Your solution causes the matrix to be copied and re-allocated on every row removed.
So, you would be better off if you calculate the resulting matrix size in advance:
new_matrix = zeros(sum(missing_vector), 5)
and then your iteration would work:
index_new=1
for index_old = 1:size(old_matrix,1)
if missing_vector(index_old) ==0
new_matrix(index_new,:) = old_matrix(index_old,:);
end
end
Try compact MATLAB code
matrix_num(missing_matrix>=0,:)=[]
Note : You must make a vector for missing_matrix variable. If this variable is matrix, you need other form of code .
As I know, you can use it in cell array too.

Access multiple elements and assign to each selected element a different value

I need to know if there is any efficient way of doing the following in MATLAB.
I have several big sparse matrices, the size of each one is roughly 9000000x9000000.
I need to access multiple element of such matrix and assign to each selected element a different value stored in another array. I'll give an example:
What I have:
SPARSE MATRIX of size 9000000x9000000
Matrix with the list of indexes and values I want to access, this is a matrix like this:
[row1, col1, value1;
row2, col2, value2;
...
rowN, colN, valueN]
Where N is the length of such matrix.
What I need:
Assign to the SPARSE MATRIX the corresponding value to the corresponding index, this is:
SPARSE_MATRIX(row1, col1) = value1
SPARSE_MATRIX(row2, col2) = value2
...
SPARSE_MATRIX(rowN, colN) = valueN
Thanks in advance!
EDIT:
Thank you to both for answering, I think I did not explain myself well, I'll try again.
I already have a large SPARSE MATRIX of about 9000000 rows x 9000000 columns, it is a SPARSE MATRIX filled with zeros.
Then I have another array or matrix, let's call it M with N number of rows, where N could take values from 0 to 9000000; and 3 columns. The first two columns are used to index an element of my SPARSE MATRIX, and the third column stores the value I want to transfer to the SPARSE MATRIX, this is, given a random row of M, i:
SPARSE_MATRIX(M(i, 1), M(i, 2)) = M(i, 3)
The idea is to do that for all the rows, I have tried it with common indexing:
SPARSE_MATRIX(M(:, 1), M(:, 2)) = M(:, 3)
Now I would like to do this assignation for all the rows in M as fast as possible, because if I use a loop or common indexing it takes ages (I am using a 7th Gen i7 processor with 16 GB of RAM). And I also need to keep the zeros in the SPARSE_MATRIX.
EDIT 2: SOLVED! Thank you Metahominid, I was not thinking through, but yes the sparse function does solve my problem, I just think my brain circuits were shortcircuited yesterday and was unable to see through it hahaha. Thank you to both anyway!
Regards!
You can construct a sparse matrix like this.
A = sparse(i,j,v)
S = sparse(i,j,v) generates a sparse matrix S from the triplets i, j,
and v such that S(i(k),j(k)) = v(k). The max(i)-by-max(j) output
matrix has space allotted for length(v) nonzero elements. sparse adds
together elements in v that have duplicate subscripts in i and j.
So you can simply construct the row vector, column vector and value vector.
I am answering in part because I cannot comment. You question seems a little confusing to me. The sparse() function in MATLAB does just this.
You can enter your arrays of indices and values directly into the interface, or declare a sparse matrix of zeros and set each individually.
Given your data format make three vectors, ROWS = [row1; ...; rown], COLS = [col1; ...; coln], and DATA = [val1; ... valn]. I am assuming that your size is the overall size of the full matrix and not the sparse portion.
Then
A = sparse(ROWS, COLS, DATA) will do just what you want. You can even specify the original matrix size.
A = sparse(ROWS, COLS, DATA, 90...., 90....).

How do I reshape a non-quadratic matrix?

I have a column vector A with dimensions (35064x1) that I want to reshape into a matrix with 720 lines and as many columns as it needs.
In MATLAB, it'd be something like this:
B = reshape(A,720,[])
in which B is my new matrix.
However, if I divide 35604 by 720, there'll be a remainder.
Ideally, MATLAB would go about filling every column with 720 values until the last column, which wouldn't have 720 values; rather, 504 values (48x720+504 = 35064).
Is there any function, as reshape, that would perform this task?
Since I am not good at coding, I'd resort to built-in functions first before going into programming.
reshape preserves the number of elements but you achieve the same in two steps
b=zeros(720*ceil(35604/720),1); b(1:35604)=a;
reshape(b,720,[])
A = rand(35064,1);
NoCols = 720;
tmp = mod(numel(A),NoCols ); % get the remainder
tmp2 = NoCols -tmp;
B = reshape([A; nan(tmp2,1)],720,[]); % reshape the extended column
This first gets the remainder after division, and then subtract that from the number of columns to find the amount of missing values. Then create an array with nan (or zeros, whichever suits your purpose best) to pad the original and then reshape. One liner:
A = rand(35064,1);
NoCols = 720;
B = reshape([A; nan(NoCols-mod(numel(A),NoCols);,1)],720,[]);
karakfa got the right idea, but some error in his code.
Fixing the errors and slightly simplifying it, you end up with:
B=nan(720,ceil(numel(a)/720));
B(1:numel(A))=A;
Create a matrix where A fits in and assingn the elemnent of A to the first numel(A) elements of the matrix.
An alternative implementation which is probably a bit faster but manipulates your variable b
%pads zeros at the end
A(720*ceil(numel(A)/720))=0;
%reshape
B=reshape(A,720,[]);

Recognise that numbers in a row of a matrix are all the same number

I have a matrix of 0s, 1s, 2s and 3s.If all the elements in the same row are the same then I want it to display the text 'flush'. For example, I have the matrix
[0,1,0,2,3;
0,0,0,0,0;
3,2,1,3,1;
2,2,2,2,2];
How would I program Matlab to recognise the 2nd and 4th row all have the same number?
A = [0,1,0,2,3; 0,0,0,0,0; 3,2,1,3,1; 2,2,2,2,2]
As it was said before if you only have positive numbers you can use the variance.
n_flush = var(A, [], 2) == 0
However, this will fail for negative numbers for example a row like [-2 -1 1 2].
What I would do is to compare the first column with the rest and flag the rows where all the elements are equal.
n_flush = all(bsxfun(#eq, A(:,1), A(:,2:end)),2)
Now, if you want to display flush every time the rows are equal you can do
for ind = find(n_flush)
fprintf('flush row %i\n', ind)
end
If you need to have the whole thing in a one-liner (which is what many Matlab-geeks try to do), then maybe this here will suit your needs
cellfun(#(x) char((x==0)*sprintf('flush')), num2cell(var(A')'), 'UniformOutput', false)
Edit: nice idea GameOfThrows
Yet another solution by explicitly subtracting the first column from each column via duplicating the first column to other columns of a matching-sized matrix.
identical_rows = ~any(A - kron(ones(1,size(A,2)),A(:,1)),2)

replace all numbers in a matrix

There are two matrices; the first one is my input matrix
and the second one ("renaming matrix") is used to replace the values of the first one
That is, looking at the renaming matrix; 701 must be replaced by 1,...,717 must be replaced by 10,etc.. such that the input matrix becomes as such
The ? values are defined but i didn't put them. The second column of the input matrix is already sorted(ascending order from top down) but the values are not consecutive(no "710": see first pic).
The question is how to get the output matrix(last pic) from the first two.
Looks to me like it's screaming for a sparse matrix solution. In matlab you can create a sparse matrix with the following command:
SM = sparse( ri, ci, val );
where ri is the row index of the non-zero elements, ci is the corresponding column index, and val is the values.
Let's call your input matrix IM and your lookup matrix LUM, then we construct the sparse matrix:
nr = size(LUM, 1);
SM = sparse( ones(nr, 1), LUM(:, 1), LUM(:, 2) );
Now we can get your result in a single line:
newMatrix = reshape(SM(1, IM), size(IM));
almost magic.
I didn't have a chance to check this tonight - but if it doesn't work exactly as described, it should be really really close...
If the values in the first column all appear in the second column, and if all you want is replace the values in the second column by 1..n and change the values in the first column accordingly, you can do all of this with a simple call to ismember:
%# define "inputMatrix" here as the first array in your post
[~,newFirstColumn] = ismember(inputMatrix(:,1),inputMatrix(:,2));
To create your output, you'd then write
outputMatrix = [newFirstColumn,(1:length(newFirstColumn))'];
If M is the original matrix and R is the renaming matrix, here's how you do it
N = M;
for n = 1:size(M,1)
N(find(M==R(n,1))) = R(n,2);
end
Note that in this case you're creating a new matrix N with the renamed values. You don't have to do that if you like.