Sorting a 2D numpy array by multiple axes
Using lexsort:
import numpy as np
a = np.array([(3, 2), (6, 2), (3, 6), (3, 4), (5, 3)])
ind = np.lexsort((a[:,1],a[:,0]))
a[ind]
# array([[3, 2],
# [3, 4],
# [3, 6],
# [5, 3],
# [6, 2]])
a.ravel()
returns a view if a
is C_CONTIGUOUS
. If that is true,
@ars's method, slightly modifed by using ravel
instead of flatten
, yields a nice way to sort a
in-place:
a = np.array([(3, 2), (6, 2), (3, 6), (3, 4), (5, 3)])
dt = [('col1', a.dtype),('col2', a.dtype)]
assert a.flags['C_CONTIGUOUS']
b = a.ravel().view(dt)
b.sort(order=['col1','col2'])
Since b
is a view of a
, sorting b
sorts a
as well:
print(a)
# [[3 2]
# [3 4]
# [3 6]
# [5 3]
# [6 2]]
Sorting A 2-Dimensional Array on Multiple Axes
Why don't you try python's sorted
:
sorted(tasks, key=lambda x: (x[2],x[0]))
Output:
[['UYWEQ', '2017-04-23', '2017-07-18', 'Corey', 'Kyle', 'Reuben', 'Kai'],
['DNMDC', '2017-06-19', '2017-08-07', 'Kaleb', 'Kai', 'Kyle', 'Reuben'],
['NSXEN', '2017-08-20', '2017-09-18', 'Kai'],
['LIVNH', '2017-11-01', '2017-12-24', 'Kaleb', 'Kai'],
['LNWBN', '2017-08-13', '2017-12-24', 'Corey', 'Kyle', 'Kaleb', 'Reuben']]
Sorting a 2D numpy array by multiple axes
Using lexsort:
import numpy as np
a = np.array([(3, 2), (6, 2), (3, 6), (3, 4), (5, 3)])
ind = np.lexsort((a[:,1],a[:,0]))
a[ind]
# array([[3, 2],
# [3, 4],
# [3, 6],
# [5, 3],
# [6, 2]])
a.ravel()
returns a view if a
is C_CONTIGUOUS
. If that is true,
@ars's method, slightly modifed by using ravel
instead of flatten
, yields a nice way to sort a
in-place:
a = np.array([(3, 2), (6, 2), (3, 6), (3, 4), (5, 3)])
dt = [('col1', a.dtype),('col2', a.dtype)]
assert a.flags['C_CONTIGUOUS']
b = a.ravel().view(dt)
b.sort(order=['col1','col2'])
Since b
is a view of a
, sorting b
sorts a
as well:
print(a)
# [[3 2]
# [3 4]
# [3 6]
# [5 3]
# [6 2]]
How to sort a 2d numpy array by the columns with the biggest sum
I'm not sure if your solution is incorrect, but it is certainly more complicated than necessary:
>>> a = np.array([[5, 3, 13],
[1, 2, 20],
[6, 2, 6]])
>>> a[:, a.sum(axis=0).argsort()] # sort columns small-to-large
array([[ 3, 5, 13],
[ 2, 1, 20],
[ 2, 6, 6]])
>>> a[:, (a.sum(axis=0)*-1).argsort()] # multiply sums by -1 to sort large-to-small
array([[13, 5, 3],
[20, 1, 2],
[ 6, 6, 2]])
Sorting arrays in NumPy by column
@steve's answer is actually the most elegant way of doing it.
For the "correct" way see the order keyword argument of numpy.ndarray.sort
However, you'll need to view your array as an array with fields (a structured array).
The "correct" way is quite ugly if you didn't initially define your array with fields...
As a quick example, to sort it and return a copy:
In [1]: import numpy as np
In [2]: a = np.array([[1,2,3],[4,5,6],[0,0,1]])
In [3]: np.sort(a.view('i8,i8,i8'), order=['f1'], axis=0).view(np.int)
Out[3]:
array([[0, 0, 1],
[1, 2, 3],
[4, 5, 6]])
To sort it in-place:
In [6]: a.view('i8,i8,i8').sort(order=['f1'], axis=0) #<-- returns None
In [7]: a
Out[7]:
array([[0, 0, 1],
[1, 2, 3],
[4, 5, 6]])
@Steve's really is the most elegant way to do it, as far as I know...
The only advantage to this method is that the "order" argument is a list of the fields to order the search by. For example, you can sort by the second column, then the third column, then the first column by supplying order=['f1','f2','f0'].
Numpy sorting 2d array by descending and take first N from each row
Using numpy.argsort()
returns an array of indices for the sorted array. As such, what your out_arr1
lets you know is where on each row to find the highest values.
If you are to continue this way, what you would need to do is for each row in in_arr (hereby written as in_arr[i]
) take values found at the first 3 indices in out_arr1[i]
.
What that means is that out_arr1[i, 0]
tells you where the highest value in in_arr on row i
is located. In our case, out_arr1[0, 0] = 3
, which means the highest value in row 0 is 40 (on index 3)
Doing this, the 3 largest numbers on each row are represented by out_arr1[0, 0]
, out_arr1[0, 1]
, out_arr1[0, 2]
and out_arr1[1, 0]
, out_arr1[1, 1]
, out_arr1[1, 2]
.
to get the desired output, we would need something along the lines of:
final_arr = numpy.array([in_arr[0, out_arr1[0, 0], in_arr[0, out_arr1[0, 1], in_arr[0, out_arr1[0, 2], in_arr[1, out_arr1[1, 0], in_arr[1, out_arr1[1, 1], in_arr[1, out_arr1[1, 2]])
This however, is less than elegant, and there is another, easier solution to your problem.
Using numpy.sort()
instead of numpy.argsort()
we can return the exact values of in_arr
sorted along an axis. By doing that, we no longer need to use an output index to find our 3 highest values, as they are the first 3 in our new output.
Considering out_arr2
as the output from numpy.sort()
, the final array would look like:
final_arr = numpy.array([[out_arr[0, 0], out_arr[0, 1], out_arr[0, 2]], [out_arr[1, 0], out_arr[1, 1], out_arr[1, 2]]])
How to using numpy.argsort on a 2D array to sort another 2D array
np.take_along_axis
has an example using argsort
:
>>> a = np.array([[10, 30, 20], [60, 40, 50]])
We can sort either by using sort directly, or argsort and this function
>>> np.sort(a, axis=1)
array([[10, 20, 30],
[40, 50, 60]])
>>> ai = np.argsort(a, axis=1); ai
array([[0, 2, 1],
[1, 2, 0]])
>>> np.take_along_axis(a, ai, axis=1)
array([[10, 20, 30],
[40, 50, 60]])
This streamlines a process of applying ai
to the array itself. We can do that directly, but it requires a bit more thought about what the index actually represents.
In this example, ai
are index values along axis 1 (values like 0,1,or 2). This (2,3) has to broadcast
with a (2,1) array for axis 0:
In [247]: a[np.arange(2)[:,None], ai]
Out[247]:
array([[10, 20, 30],
[40, 50, 60]])
How to sort a 2D array of two columns, from large to small, by the second column?
Assuming your array is as below, you could do:
import numpy as np
representative_models = np.array([[' A1', '1347'],
[' A4', '1381'],
[' Q3', '1417'],
[' A3', '1929'],
[' A6', '748'],
[' Q2', '822'],
[' Q5', '877'],
[' A5', '882']])
# convert last column to int and arg-sort in decreasing order [::-1]
order = np.argsort(representative_models[:, 1].astype(int))[::-1]
# simply index on the input array
result = representative_models[order, :]
print(result)
Output
[[' A3' '1929']
[' Q3' '1417']
[' A4' '1381']
[' A1' '1347']
[' A5' '882']
[' Q5' '877']
[' Q2' '822']
[' A6' '748']]
How to sort each row of a 3D numpy array by another 2D array?
If I understand you correctly, you want this:
norms = np.linalg.norm(a,axis=2) # shape(3,4)
indices = np.argsort(norms , axis=1)
np.take_along_axis(a, indices[:,:,None], axis=1)
output for your example:
[[[0.4236548 0.64589411]
[0.60276338 0.54488318]
[0.5488135 0.71518937]
[0.43758721 0.891773 ]]
[[0.07103606 0.0871293 ]
[0.79172504 0.52889492]
[0.96366276 0.38344152]
[0.56804456 0.92559664]]
[[0.0202184 0.83261985]
[0.46147936 0.78052918]
[0.77815675 0.87001215]
[0.97861834 0.79915856]]]
Related Topics
Split a List into Nested Lists on a Value
How to Change UI in Same Window Using Pyqt5
Error Loading Dll in Python, Not a Valid Win32 Application
Installing Module from Github Through Jupyter Notebook
Tab Completion in Python's Raw_Input()
Redirect While Passing Arguments
Typeerror: 'List' Object Is Not Callable While Trying to Access a List
I'm Getting "Typeerror: 'List' Object Is Not Callable". How to Fix This Error
Python's in (_Contains_) Operator Returns a Bool Whose Value Is Neither True Nor False
Removing Entries from a Dictionary Based on Values
How to Find Unused Functions in Python Code
How to Print a Dictionary's Key
Reading Two Text Files Line by Line Simultaneously