Karthik Venkatesh
Karthik Venkatesh

Reputation: 319

Sort a 1D array and a 2D array(by column) simultaneously

I have two arrays, a 1D array called Amplitudes with shape (99,) and a 2D array called Modes with a shape (55714,99). I want to sort these two arrays such that, the columns of the Modes array arranges according to the Amplitudes. This is actually done in order to find the dominant Modes.

Amplitudes_absolute is my 1D array and Modes_st is my 2D array. Both are unsorted.

Amplitudes_absolute.shape gives (99,) Modes_st.shape gives me (55714,99)

I want to retain the shape of the Sorted Modes as (55714,99) but with the columns sorted according the ascending values of the Amplitudes_absolute.

I tried:

Amplitudes_absolute_sorted, Modes_sorted = [list(x) for x in     zip(*sorted(zip(Amplitudes_absolute, Modes_st), key=itemgetter(0)))]

Modes_sorted = np.squeeze(np.array(Modes_sorted)) #To obtain an array

and

Amplitudes_absolute_sorted = np.sort(Amplitudes_absolute)

p = Amplitudes_absolute_sorted.argsort()

Modes_sorted = Modes_st[p]

Both gave me the wrong shape, as in Modes_sorted.shape gives (99,99) and not (55714,99).

Is there a way to do this sorting?

Upvotes: 1

Views: 908

Answers (1)

user2379410
user2379410

Reputation:

You were very close. The first approach can be fixed by transposing the modes array:

from operator import itemgetter
import numpy as np

_, modes_sorted = zip(*sorted(zip(amplitudes, modes.T), key=itemgetter(0)))
modes_sorted = np.array(modes_sorted)

This is because when you iterate a 2D Numpy array you get the rows, but you need the columns. You only got the first 99 rows with the original code, because zip stops when one of the iterators it receives is exhausted.

Of course with Numpy it's easier to do:

sorter = amplitudes.argsort()
modes_sorted = modes[:,sorter]

Note the : for the first index, so we are rearranging the columns and not the rows. Also, there is no need to sort amplitudes first, you can just use argsort directly.

Upvotes: 1

Related Questions