Sortowanie tablic w NumPy według kolumn
Jak mogę posortować tablicę w NumPy według n-tej kolumny?
Na przykład,
a = array([[9, 2, 3],
[4, 5, 6],
[7, 0, 5]])
Chciałbym sortować wiersze po drugiej kolumnie, tak, że wrócę:
array([[7, 0, 5],
[9, 2, 3],
[4, 5, 6]])
14 answers
@steve'S answer jest właściwie najbardziej eleganckim sposobem na zrobienie tego.
Aby uzyskać "poprawny" sposób zobacz argument słowa kluczowego order numpy.ndarray.Sortuj
Musisz jednak wyświetlić tablicę jako tablicę z polami (tablica strukturalna).
"poprawny" sposób jest dość brzydki, jeśli początkowo nie zdefiniowano tablicy z polami...
Jako szybki przykład, aby go posortować i zwrócić kopię:
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]])
Do sortowania 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 naprawdę jest najbardziej eleganckim sposobem, aby to zrobić, o ile wiem...
Jedyną zaletą tej metody jest to, że argument "order"jest listą pól, według których można uporządkować wyszukiwanie. Na przykład możesz sortować według drugiej kolumny, następnie trzeciej kolumny, a następnie pierwszej kolumny, podając order=['f1', 'f2', 'f0'].
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-16 00:22:50
To chyba działa: a[a[:,1].argsort()]
Oznacza to drugą kolumnę a
i odpowiednio ją posortować.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-12-10 10:17:01
Możesz sortować na wielu kolumnach zgodnie z metodą Steve ' a Tjoa, używając stabilnego sortowania, takiego jak mergesort i sortując indeksy od najmniej znaczących do najbardziej znaczących kolumn:
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')]
Sortuje według kolumny 0, potem 1, Potem 2.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-25 22:37:00
Z wiki dokumentacji Pythona , myślę, że możesz to zrobić:
a = ([[1, 2, 3], [4, 5, 6], [0, 0, 1]]);
a = sorted(a, key=lambda a_entry: a_entry[1])
print a
Wyjście To:
[[[0, 0, 1], [1, 2, 3], [4, 5, 6]]]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-26 10:00:05
Jeśli ktoś chce skorzystać z sortowania w krytycznej części swoich programów, oto porównanie wydajności dla różnych propozycji:
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
Wygląda więc na to, że indeksowanie za pomocą argsort jest jak dotąd najszybszą metodą...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-25 10:37:19
Z listy dyskusyjnej NumPy , oto inne rozwiązanie:
>>> a
array([[1, 2],
[0, 0],
[1, 0],
[0, 2],
[2, 1],
[1, 0],
[1, 0],
[0, 0],
[1, 0],
[2, 2]])
>>> a[np.lexsort(np.fliplr(a).T)]
array([[0, 0],
[0, 0],
[0, 2],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 2],
[2, 1],
[2, 2]])
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-26 10:00:55
Miałem podobny problem.
Mój Problem:
Chcę obliczyć SVD i muszę posortować moje wartości własne W porządku malejącym. Ale chcę zachować mapowanie między wartościami własnymi i wektorami własnymi. Moje wartości własne były w pierwszym wierszu, a odpowiadający im wektor wewnętrzny pod nim w tej samej kolumnie.
Chcę więc posortować dwuwymiarową tablicę kolumn według pierwszego wiersza w porządku malejącym.
Moje Rozwiązanie
a = a[::, a[0,].argsort()[::-1]]
Więc jak czy to działa?
a[0,]
to tylko pierwszy rząd, który chcę sortować według.
Teraz używam argsort aby uzyskać kolejność indeksów.
Używam [::-1]
ponieważ potrzebuję malejącej kolejności.
Na koniec używam a[::, ...]
, aby uzyskać widok z kolumnami w odpowiedniej kolejności.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-26 10:09:52
import numpy as np
a=np.array([[21,20,19,18,17],[16,15,14,13,12],[11,10,9,8,7],[6,5,4,3,2]])
y=np.argsort(a[:,2],kind='mergesort')# a[:,2]=[19,14,9,4]
a=a[y]
print(a)
Pożądane wyjście to [[6,5,4,3,2],[11,10,9,8,7],[16,15,14,13,12],[21,20,19,18,17]]
Zauważ, że argsort(numArray)
zwraca indeksy numArray
tak, jak miało to być uporządkowane.
Przykład
x=np.array([8,1,5])
z=np.argsort(x) #[1,3,0] are the **indices of the predicted sorted array**
print(x[z]) #boolean indexing which sorts the array on basis of indices saved in z
Odpowiedź brzmi [1,5,8]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-27 09:14:07
Przykład - malejący na pierwszej kolumnie, wtórnie rosnący na drugiej. Triki z lexsort
polegają na tym, że sortuje on wiersze (stąd .T
) i nadaje pierwszeństwo ostatniemu.
In [120]: b=np.array([[1,2,1],[3,1,2],[1,1,3],[2,3,4],[3,2,5],[2,1,6]])
In [121]: b
Out[121]:
array([[1, 2, 1],
[3, 1, 2],
[1, 1, 3],
[2, 3, 4],
[3, 2, 5],
[2, 1, 6]])
In [122]: b[np.lexsort(([1,-1]*b[:,[1,0]]).T)]
Out[122]:
array([[3, 1, 2],
[3, 2, 5],
[2, 1, 6],
[2, 3, 4],
[1, 1, 3],
[1, 2, 1]])
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-07 16:33:59
Oto inne rozwiązanie uwzględniające wszystkie kolumny (bardziej zwarty sposób odpowiedzi J. J);
ar=np.array([[0, 0, 0, 1],
[1, 0, 1, 0],
[0, 1, 0, 0],
[1, 0, 0, 1],
[0, 0, 1, 0],
[1, 1, 0, 0]])
Sortuj za pomocą lexsort,
ar[np.lexsort(([ar[:, i] for i in range(ar.shape[1]-1, -1, -1)]))]
Wyjście:
array([[0, 0, 0, 1],
[0, 0, 1, 0],
[0, 1, 0, 0],
[1, 0, 0, 1],
[1, 0, 1, 0],
[1, 1, 0, 0]])
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-30 19:36:58
Po prostu używając sortowania, użyj numeru coloumn na podstawie którego chcesz sortować.
a = np.array([1,1], [1,-1], [-1,1], [-1,-1]])
print (a)
a=a.tolist()
a = np.array(sorted(a, key=lambda a_entry: a_entry[0]))
print (a)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-19 17:13:49
Jest to stare pytanie, ale jeśli trzeba uogólnić to do macierzy wyższych niż 2, Oto rozwiązanie, które można łatwo uogólnić:
np.einsum('ij->ij', a[a[:,1].argsort(),:])
Jest to przesada dla dwóch wymiarów i a[a[:,1].argsort()]
wystarczyłoby na odpowiedź @steve ' a, jednak ta odpowiedź nie może być uogólniona na wyższe wymiary. Możesz znaleźć przykład tablicy 3D w tym pytaniu.
Wyjście:
[[7 0 5]
[9 2 3]
[4 5 6]]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-27 04:59:01
#do sortowania wzdłuż kolumny 1
indexofsort=np.argsort(dataset[:,0],axis=-1,kind='stable')
dataset = dataset[indexofsort,:]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-15 08:45:00
def sort_np_array(x, column=None, flip=False):
x = x[np.argsort(x[:, column])]
if flip:
x = np.flip(x, axis=0)
return x
Tablica w pytaniu pierwotnym:
a = np.array([[9, 2, 3],
[4, 5, 6],
[7, 0, 5]])
Wynik funkcji sort_np_array
zgodnie z oczekiwaniami autora pytania:
sort_np_array(a, column=1, flip=False)
[2]: array([[7, 0, 5],
[9, 2, 3],
[4, 5, 6]])
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-31 14:58:57