How can I sort a 2-D array in MATLAB with respect to one column? - matlab

I would like to sort a matrix according to a particular column. There is a sort function, but it sorts all columns independently.
For example, if my matrix data is:
1 3
5 7
-1 4
Then the desired output (sorting by the first column) would be:
-1 4
1 3
5 7
But the output of sort(data) is:
-1 3
1 4
5 7
How can I sort this matrix by the first column?

I think the sortrows function is what you're looking for.
>> sortrows(data,1)
ans =
-1 4
1 3
5 7

An alternative to sortrows(), which can be applied to broader scenarios.
save the sorting indices of the row/column you want to order by:
[~,idx]=sort(data(:,1));
reorder all the rows/columns according to the previous sorted indices
data=data(idx,:)

Related

Finding the rows of a matrix with specified elements

I want to find the rows of a matrix which contain specified element of another matrix.
For example, a=[1 2 3 4 5 6 7] and b=[1 2 0 4;0 9 10 11;3 1 2 12]. Now, I want to find the rows of b which contain at least three element of a. For this purpose, I used bsxfun command as following:
c=find(sum(any(bsxfun(#eq, b, reshape(a,1,1,[])), 2), 3)>=3);
It works good for low dimension matrices but when I want to use this for high dimension matrices, for example, when the number of rows of b is 192799, MATLAB gives following error:
Requested 192799x4x48854 (35.1GB) array exceeds maximum array size preference.
Creation of arrays greater than this limit may take a long time and cause MATLAB
to become unresponsive. See array size limit or preference panel for more information.
Is there any other command which does this task without producing the behaviour like above for high dimension matrices?
a possible solution:
a=[1 2 3 4 5 6 7]
b=[1 2 0 4;0 9 10 11;3 1 2 12]
i=ismember(b,a)
idx = sum(i,2)
idx = find(idx>=3)

How to extend the rows of a matrix in MATLAB filling the added rows with the first row's values efficiently [duplicate]

This question already has answers here:
Building a matrix by merging the same row vector multiple times
(2 answers)
Closed 8 years ago.
I have a matrix myVel that is of size [1 501] meaning 1 row and 501 columns.
I want to extend this matrix so that the matrix will be of size [N 501], where N is an arbitrary number.
Each of the values in the columns need to be the same (meaning that all the values in the first column are all say, x and all of the values in the second column are say, y and so on).
This means that each row would consist of the same values.
How can I achieve this efficiently?
Divakar's solution is one way to do it, and the link he referenced shows some great ways to duplicate an array. That post, however, is asking to do it without the built-in function repmat, which is the easiest solution. Because there is no such restriction for you here, I will recommend this approach. Basically, you can use repmat to do this for you. You would keep the amount of columns the same, and you would duplicate for as many rows as you want. In other words:
myVelDup = repmat(myVel, N, 1);
Example:
myVel = [1 2 3 4 5 6];
N = 4;
myVelDup = repmat(myVel, N, 1);
Output:
>> myVel
myVel =
1 2 3 4 5 6
>> myVelDup
myVelDup =
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
In general, repmat is called in the following way:
out = repmat(in, M, N);
in would be a matrix or vector of values you want duplicated, and you would want to duplicate this M times horizontally (rows) and N times vertically (columns). As such, for your case, as you have an array, you will want to duplicate this N times vertically and so we set the first parameter to N. The second parameter, the columns stay the same so we specify this to be 1 as we don't want to have any duplications... and thus the call to repmat you see above.
For more information on repmat, check out this link: http://www.mathworks.com/help/matlab/ref/repmat.html

Accessing indexes as first columns of matrix in Matlab

I have data that is output from a computational chemistry program (Gaussian09) which contains sets of Force Constant data. The data is arranged with indexes as the first 2-4 columns (quadratic, cubic and quartic FC's are calculated). As an example the cubic FC's look something like this, and MatLab has read them in successfully so I have the correct matrix:
cube=[
1 1 1 5 5 5
1 1 2 6 6 6
.
.
4 1 1 8 8 8
4 2 1 9 9 9
4 3 1 7 7 7 ]
I need a way to access the last 3 columns when feeding in the indices of the first 3 columns. Something along the lines of
>>index=find([cube(:,1)==4 && cube(:,2)==3 && cube(:,3)==1]);
Which would give me the row number of the data that is index [ 4 3 1 ] and allow me to read out the values [7 7 7] which I need within loops to calculate anharmonic frequencies.
Is there a way to do this without a bunch of loops?
Thanks in advance,
Ben
You have already found one way to solve this, by using & in your expression (allowing you to make non-scalar comparisons).
Another way is to use ismember:
index = find(ismember(cube(:,1:3),[4 3 1]));
Note that in many cases, you may not even need the call to find: the binary vector returned by the comparisons or ismember can directly be used to index into another array.

matlab sort one column and keep respective values on second column

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.

Removing rows with identical first column value in matlab

I have a cell matrix of size 10000 X 3 in Matlab and I would like to remove rows with the same value in the first column.
That is, if row i and row j have the same value in the first column, I'd like to delete both rows.
I should also say that there can be more than two rows with the same value in the first column and in that case, I'd like to delete all these rows.
How do I do it?
Thanks!
You can use the functions histc, unique and logical indexing to achieve what you want. Here's a small example.
a=randi(10,5,3) %#generate a sample random matrix
a =
5 3 5
5 7 10
7 7 4
8 2 6
8 2 3
[uniqVals,uniqIndx]=unique(a(:,1)); %# get unique values and corresponding indices of the first column of a
count=histc(a(:,1),uniqVals); %# get the bin counts of the elements (i.e., find which are repeated)
b=a(uniqIndx(count==1),:)
b =
7 7 4
Only the row with the non-repeated element is selected. Since you said that you have a cell matrix, simply covert it to a matrix using cell2mat before doing this.