Sanka
Sanka

Reputation: 177

Extract values from a vector and sort them based on their original squence

I have a vector of numbers (temperatures), and I am using the MATLAB function mink to extract the 5 smallest numbers from the vector to form a new variable. However, the numbers extracted using mink are automatically ordered from lowest to largest (of those 5 numbers). Ideally, I would like to retain the sequence of the numbers as they are arranged in the original vector. I hope my problem is easy to understand. I appreciate any advice.

Upvotes: 2

Views: 127

Answers (2)

Cris Luengo
Cris Luengo

Reputation: 60444

The function mink that you use was introduced in MATLAB 2017b. It has (as Andras Deak mentioned) two output arguments:

[B,I] = mink(A,k);

The second output argument are the indices, such that B == A(I).

To obtain the set B but sorted as they appear in A, simply sort the vector of indices I:

B = A(sort(I));

For example:

>> A = [5,7,3,1,9,4,6];
>> [~,I] = mink(A,3);
>> A(sort(I))
ans =
     3     1     4

For older versions of MATLAB, it is possible to reproduce mink using sort:

function [B,I] = mink(A,k)
  [B,I] = sort(A);
  B = B(1:k);
  I = I(1:k);

Note that, in the above, you don't need the B output, your ordered_mink can be written as follows

function B = ordered_mink(A,k)
  [~,I] = sort(A);
  B = A(sort(I(1:k)));

Note: This solution assumes A is a vector. For matrix A, see Andras' answer, which he wrote up at the same time as this one.

Upvotes: 2

First you'll need the corresponding indices for the extracted values from mink using its two-output form:

[vals, inds] = mink(array);

Then you only need to order the items in val according to increasing indices in inds. There are multiple ways to do this, but they all revolve around sorting inds and using the corresponding order on vals. The simplest way is to put these vectors into a matrix and sort the rows:

sorted_rows = sortrows([inds, vals]); % sort on indices

and then just extract the corresponding column

reordered_vals = sorted_rows(:,2); % items now ordered as they appear in "array"

A less straightforward possibility for doing the sorting after the above call to mink is to take the sorting order of inds and use its inverse to reverse-sort vals:

reverse_inds = inds; % just allocation, really
reverse_inds(inds) = 1:numel(inds); % contruct reverse permutation
reordered_vals = vals(reverse_inds); % should be the same as previously

Upvotes: 1

Related Questions