Вопрос-Ответ

Sorting arrays in NumPy by column

Сортировка массивов в NumPy по столбцам

Как мне отсортировать массив NumPy по его n-му столбцу?

Например, учитывая:

a = array([[9, 2, 3],
[4, 5, 6],
[7, 0, 5]])

Я хочу отсортировать строки из a по второму столбцу, чтобы получить:

array([[7, 0, 5],
[9, 2, 3],
[4, 5, 6]])
Переведено автоматически
Ответ 1

Для сортировки по второму столбцу a:

a[a[:, 1].argsort()]
Ответ 2

Ответ @steve на самом деле является самым элегантным способом сделать это.

Для "правильного" способа смотрите аргумент ключевого слова order в numpy.ndarray.sort

Однако вам нужно будет просмотреть свой массив как массив с полями (структурированный массив).

"Правильный" способ довольно уродлив, если вы изначально не определяли свой массив с полями...

В качестве краткого примера, чтобы отсортировать его и вернуть копию:

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]])

Чтобы отсортировать их на месте:

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 действительно самый элегантный способ сделать это, насколько я знаю...

Единственное преимущество этого метода заключается в том, что аргумент "order" представляет собой список полей, по которым нужно упорядочить поиск. Например, вы можете выполнить сортировку по второму столбцу, затем по третьему столбцу, затем по первому столбцу, указав order=['f1','f2', 'f0'].

Ответ 3

Вы можете выполнять сортировку по нескольким столбцам в соответствии с методом Стива Тджоа, используя стабильную сортировку, такую как mergesort, и сортируя индексы от наименее значимых к наиболее значимым столбцам:

a = a[a[:,2].argsort()] # First sort doesn't need to be stable.
a = a[a[:,1].argsort(kind='mergesort')]
a = a[a[:,0].argsort(kind='mergesort')]

Это сортирует по столбцу 0, затем 1, затем 2.

Ответ 4

На случай, если кто-то захочет использовать сортировку в критической части своих программ, вот сравнение производительности для различных предложений:

import numpy as np
table = np.random.rand(5000, 10)

%timeit table.view('f8,f8,f8,f8,f8,f8,f8,f8,f8,f8').sort(order=['f9'], axis=0)
1000 loops, best of 3: 1.88 ms per loop

%timeit table[table[:,9].argsort()]
10000 loops, best of 3: 180 µs per loop

import pandas as pd
df = pd.DataFrame(table)
%timeit df.sort_values(9, ascending=True)
1000 loops, best of 3: 400 µs per loop

Итак, похоже, что индексирование с помощью argsort на данный момент является самым быстрым методом...

2023-08-07 18:47 python arrays sorting numpy scipy