Mengurutkan data adalah langkah persiapan yang hampir selalu muncul: nilai ujian dari terkecil, penjualan dari terbesar, atau daftar nama secara abjad. NumPy menyediakan np.sort sebagai fungsi, method sort() pada array, dan np.argsort untuk mendapatkan indeks urutan.

Ketiganya punya kontrak yang berbeda. np.sort mengembalikan salinan baru; a.sort() mengubah array asli langsung (in-place); sedangkan np.argsort tidak mengembalikan data, melainkan posisi elemen bila array tersebut diurutkan. Memilih yang keliru bisa membuat data asli berubah tanpa disadari.

np.sort dan method sort(): Salinan vs In-place #

python
import numpy as np

nilai = np.array([78, 85, 92, 69, 88])
terurut = np.sort(nilai)
print(terurut)
print(nilai)

nilai.sort()
print(nilai)

Output yang Dihasilkan:

text
[69 78 85 88 92]
[78 85 92 69 88]
[69 78 85 88 92]

Mari kita periksa:

  1. Baris 4 (terurut = np.sort(nilai)): NumPy mengembalikan array baru berisi nilai terurut menaik (ascending). Array nilai tidak tersentuh — terbukti pada Baris 6 yang masih mencetak [78 85 92 69 88].
  2. Baris 8 (nilai.sort()): method sort() mengurutkan buffer array asli secara langsung (in-place) dan mengembalikan None, bukan array terurut.
  3. Baris 9: setelah method dipanggil, nilai sendiri berubah menjadi [69 78 85 88 92].

argsort: Mendapatkan Indeks Urutan #

np.argsort menjawab pertanyaan “indeks ke berapa yang membuat data terurut?”, bukan “datanya apa?”. Hasilnya berupa array indeks yang bisa dipakai untuk mengurutkan array lain yang sebaris dengannya.

python
import numpy as np

nilai = np.array([78, 85, 92, 69, 88])
urutan = np.argsort(nilai)
print(urutan)
print(nilai[urutan])
print(np.sort(nilai)[::-1])

Output yang Dihasilkan:

text
[3 0 1 4 2]
[69 78 85 88 92]
[92 88 85 78 69]

Penjelasannya:

  1. Baris 4 (np.argsort(nilai)): elemen terkecil 69 berada di indeks 3, berikutnya 78 di indeks 0, dan seterusnya — hasilnya [3 0 1 4 2].
  2. Baris 6 (nilai[urutan]): fancy indexing dengan array indeks mengambil elemen sesuai urutan tersebut, sehingga hasilnya identik dengan np.sort(nilai). Teknik ini penting saat ada kolom lain yang harus mengikuti urutan yang sama.
  3. Baris 7 (np.sort(nilai)[::-1]): slice [::-1] membalik salinan yang baru saja dibuat np.sort, menghasilkan urutan menurun (descending). Aman dilakukan karena np.sort mengembalikan salinan segar — array asli tetap utuh.

Pengurutan per Baris dan per Kolom #

Pada array dua dimensi, parameter axis menentukan arah pengurutan: axis=1 mengurutkan di dalam setiap baris, sedangkan axis=0 mengurutkan di dalam setiap kolom.

python
import numpy as np

penjualan = np.array([
    [120, 85, 200, 65],
    [90, 150, 110, 40],
    [175, 60, 95, 130],
])
print(np.sort(penjualan, axis=1))
print(np.sort(penjualan, axis=0))

Output yang Dihasilkan:

text
[[ 65  85 120 200]
 [ 40  90 110 150]
 [ 60  95 130 175]]
[[ 90  60  95  40]
 [120  85 110  65]
 [175 150 200 130]]

Yang terjadi:

  1. Baris 8 (axis=1): setiap baris diurutkan sendiri-sendiri; baris pertama [120 85 200 65] menjadi [ 65 85 120 200].
  2. Baris 9 (axis=0): setiap kolom diurutkan sendiri-sendiri; kolom pertama [120 90 175] menjadi [ 90 120 175].
  3. Tanpa parameter, np.sort memakai axis=-1 — sumbu terakhir, yang pada array dua dimensi berarti per baris.

Mengurutkan dengan Beberapa Kunci via lexsort #

Data nyata sering butuh lebih dari satu kunci: urutkan menurut divisi, lalu di dalam divisi yang sama menurut gaji. np.lexsort menerima tuple berisi array kunci dan mengembalikan indeks urutannya. Urutan kunci dibaca dari kanan ke kiri: kunci paling kanan adalah kunci utama.

python
import numpy as np

divisi = np.array(["A", "B", "A", "B", "A"])
gaji = np.array([5000, 4000, 6000, 4500, 5500])
urutan = np.lexsort((gaji, divisi))
print(urutan)
print(divisi[urutan])
print(gaji[urutan])

Output yang Dihasilkan:

text
[0 4 2 1 3]
['A' 'A' 'A' 'B' 'B']
[5000 5500 6000 4000 4500]

Penjelasannya:

  1. Baris 5 (np.lexsort((gaji, divisi))): kunci paling kanan (divisi) menjadi kunci utama; gaji menjadi pemecah seri di dalam divisi yang sama.
  2. Baris 6: hasil [0 4 2 1 3] berarti karyawan indeks 0, 4, 2 (semua divisi A, gaji menaik 5000, 5500, 6000), lalu indeks 1, 3 (divisi B, gaji 4000, 4500).
  3. Baris 7-8: indeks yang sama diterapkan ke kedua array, sehingga baris “karyawan” tetap konsisten pada semua kolom.

Tabel berikut merangkum kontrak setiap cara mengurutkan:

EkspresiHasilArray asli
np.sort(a)salinan baru yang teruruttetap
a.sort()None; buffer a diubah langsungberubah
np.argsort(a)array indeks urutantetap
np.lexsort((k2, k1))array indeks multi-kunci, k1 utamatetap