Loren on the Art of MATLAB

Turn ideas into MATLAB

Note

Loren on the Art of MATLAB has been archived and will not be updated.

Constrained Sorting of Arrays

In a variety of applications, customers have requested a way to sort arrays subject to some constraints. One use case is when a row in an array represents a data record. Clearly, to sensibly sort data of this kind, you need to keep each row in tact. The sort function in MATLAB gives you one tool, the permutations, as the second output so you can do secondary array manipulations with it. With character arrays and cell arrays of strings, it made sense to do a lexical sort, which you can do with the function sortrows.

Contents

Regular Sorting

Suppose you have a numeric array A and want to sort the vytalues in each column. All you have to do is apply the functionjj sort.

A = [1 200 300;
2 200 200;
3 100 100;];
sort(A)
ans =
     1   100   100
     2   200   200
     3   200   300

To generate the permutations used in the sorting, use a second output.

[~, ind] = sort(A);

Sort by a Particular Column

I can also choose to sort all of A by a particular column. First sort that column, and then use those indices to sort the entire array.

[~, index2] = sort(A(:,2));
Asort2 = A(index2,:)
Asort2 =
     3   100   100
     1   200   300
     2   200   200

I can reorder another matrix B according to the sort order for column 2 generated by sorting A. You might want to do something akin to this if you reorder an array of eigenvalues and want to reorder the associated eigenvectors.

B = reshape(1:9,3,3)
B(index2,:)
B =
     1     4     7
     2     5     8
     3     6     9
ans =
     3     6     9
     1     4     7
     2     5     8

Use sortrows for an easier way to keep row data together upon sorting. I can do so while choosing which column to sort by.

Asortrows2 = sortrows(A,2)
Asortrows2 =
     3   100   100
     1   200   300
     2   200   200

This is the same result as that achieved earlier with sort and indexing combined.

isequal(Asort2, Asortrows2)
ans =
     1

Sort with Secondary Sort

Suppose I want to keep rows in tact, and sort an array according to values in a particular column, and break ties in sorting according to another column. I can do that with sortrows as well.

sortrows(A, [2, 1])
ans =
     3   100   100
     1   200   300
     2   200   200

Sorting Strings

I can use sortrows to sort a cell array of strings alphabetically.

str = {'one'; 'two'; 'three'; 'four'; 'five'}
strsort = sortrows(str)
str = 
    'one'
    'two'
    'three'
    'four'
    'five'
strsort = 
    'five'
    'four'
    'one'
    'three'
    'two'

Sorting a 2-D Array of Strings

Suppose I have a 2-D cell array of strings now. I can sort each column of strings, independent of each other (like sort does for numeric values), getting the sorting permutation in a second output if I wish.

xt = str';
xta  = [xt; xt(randperm(5)); xt(randperm(5))]
[xtasort,indexxta] = sortrows(xta)
xta = 
    'one'     'two'      'three'    'four'     'five'
    'five'    'four'     'one'      'three'    'two' 
    'five'    'three'    'one'      'four'     'two' 
xtasort = 
    'five'    'four'     'one'      'three'    'two' 
    'five'    'three'    'one'      'four'     'two' 
    'one'     'two'      'three'    'four'     'five'
indexxta =
     2
     3
     1

And I can sort the string rows according to contents of specific columns.

[xta23,indexxta23] = sortrows(xta,[2,3])
xta23 = 
    'five'    'four'     'one'      'three'    'two' 
    'five'    'three'    'one'      'four'     'two' 
    'one'     'two'      'three'    'four'     'five'
indexxta23 =
     2
     3
     1

Assorted Sorting?

In addition to what I've mentioned, you can choose to sort, via the function sort, in descending order in addition to ascending. What sort of sorting do you need to do with your data and algorithms? Do you use lexical sorting? How about dependent sorts, e.g., according to some specific columns, or according to the sort order of an array of data? Let me know here.




Published with MATLAB® 7.9


  • print