I would like to sort a matrix in ascending order, however I do not want to affect the third column. For example, the sorted version of
A= [ 2 1 3;
5 4 1;
4 3 2]
Would be
B= [1 2 3;
4 5 1;
3 4 2]
Matlab provides quite a bit of inhouse help so using help FUNCTION/CLASS would have provided you with the below information. If you don't know the FUNCTION\CLASS name use lookfor TERM for a list of matches or alternately docsearch TERM.
Stock matlab provides both sort and sortrows. You'll be needing the latter.
sortrows(X,C)
Where C is a list of column indices to sort by whose sign may be positive corresponding for ascending order or negative for descending order.
In your example you'll want this :
sortrows(A',[1,2])'
The ' indicates to matlab that you need the matrix transposed, which basically swaps rows and columns before and after sortrows is called.
You can just sort the 1st two columns and update the matrix accordingly:
edit: updated dimension
A(:,1:2) = sort(A(:,1:2),2);
Related
I have a matrix A and a vector b. I don't know their sizes, the size varies because it is the output of another function. What I want to do is filter A by a column (let's say jth column) which has at least one value that is in b.
How do I do this without measuring the size of b and concatenating every filtered result. Right now, the code is like this (assume j is a given value)
bsize=size(b,1);
for i=1:bsize
if i==1
a=A(A(:,j)==b(i),:);
else
a=[a; A(A(:,j)==b(i),:)];
end
end
I want to code a faster solution.
I am adding a numerical example just to make it clear. Let's say
A=[2 4
7 14
11 13
15 14]
and b=[4 14]
What I'm trying to do is filter to obtain the A matrix whose values are 4 and 14 in the second column, the elements of b to obtain the following output.
A=[2 4
7 14
15 14]
In my data A has more than 12000 rows and b has more than 100 elements. It doesn't always have to be the second column, sometimes the column index changes but that's not the problem now.
Use the ismember function to create a logical index based on column j=2 of A and vector b, and use that index into the rows of A:
output = A(ismember(A(:,j), b), :);
In MATLAB, we can operate on both rows and columns of a matrix. What does it exactly mean by "row major" or "column major"?
It is important to understand that MATLAB stores data in column-major order, so you know what happens when you apply the colon operator without any commas:
>> M = magic(3)
M =
8 1 6
3 5 7
4 9 2
>> M(:)
ans =
8
3
4
1
5
9
6
7
2
I tend to think "MATLAB goes down, then across". This makes it easy to reshape and permute arrays without scrambling your data. It's also necessary in order to grasp linear indexing (e.g. M(4)).
For example, a common way to obtain a column vector inline from some expression that generates an array is:
reshape(<array expression>,[],1)
As with (:) this stacks all the columns on top of each other into single column vector, for all data in any higher dimensions.
But this nifty syntactic trick lets you avoid an extra line of code.
In MATLAB, arrays are stored in column major order.
It means that when you have a multi-dimensional array, its 1D representation in memory is such that leftmost indices change faster.
It's called column major order because for a 2D array (matrix), the first (leftmost) index is typically the row index, so since it changes faster than the second (next to the right) index, the 1D representation of the matrix is memory correspond to the concatenation of the columns of the matrix.
Suppose I have a vector B=[1 1 2 2] and A=[5 6 7 4] in the form of B says the numbers in the A that are need to be summed up. That is we need to sum 5 and 6 as the first entry of the result array and sum 7 and 4 as the second entry. If B is [1 2 1 2] then first element of the result is 5+7 and second element is 6+4.
How could I do it in Matlab in generic sense?
A fexible and general approach would be to use accumarray().
accumarray(B',A')
The function accumulates the values in A into the positions specified by B.
Since the documentation is not simple to understand I will summarize why it is flexible. You can:
choose your accumulating function (sum by default)
specify the positions as a set of coordinates for accumulation into ND arrays
preset the dimension of the accumulated array (by default it expands to max position)
pad with custom values the non accumulated positions (pads with 0 by default)
set the accumulated array to sparse, thus potential avoiding out of memory
[sum(A(1:2:end));sum(A(2:2:end))]
How do I just do a simple sort in matlab. I always have to use the excel link to import my data, sort it, then export back to matlab. This is annoying!!!
I have one matrix <10x10> and I want to sort the first column in descending order while keeping it's respective values on the second column. Matlab seems to just sort each column individually.
Example:
matrix a
5 4
8 9
0 6
7 3
matrix b (output)
0 6
5 4
7 3
8 9
The sortrows answer by #chaohuang is probably what you're looking for. However, it sorts based on all columns. If you only want to sort based on the first column, then you can do this:
% sort only the first column, return indices of the sort
[~,sorted_inds] = sort( a(:,1) );
% reorder the rows based on the sorted indices
b = a(sorted_inds,:);
Simply use b=sortrows(a); See here.
I am trying to copy a few elements from a matrix, but not a whole row, and not a single element.
For example, in the following matrix:
a = 1 2
3 4
5 6
7 8
9 0
How would I copy out just the following data?
b = 1
3
5
i.e. rows 1:3 in column 1 only... I know that you can remove an entire column like this:
b = a(:,1)
... and I appreciate that could just do this and then dump the last two rows, but I'd like to use more streamlined code as I am running a very resource-intensive solution.
Elements in a matrix in MATLAB are stored in column-major order. Which means, you could even use a single index and say:
b = a(1:3);
Since the first 3 elements ARE 1,3,5. Similarly, a(6) is 2, a(7) is 4 etc. Look at the sub2ind method to understand more:
http://www.mathworks.com/help/techdoc/ref/sub2ind.html
You are not "removing" the second column, you are referencing the other column.
You should read some of the Matlab docs, they provide some help about the syntax for accessing portions of matrices:
http://www.mathworks.com/help/techdoc/learn_matlab/f2-12841.html#f2-428