Pemecahan (split) adalah kebalikan penyusunan, yaitu membagi satu array menjadi beberapa array yang lebih kecil. Topik ini membahas np.split beserta variasinya np.vsplit dan np.hsplit, aturan jumlah bagian yang wajib rata, serta alternatif np.array_split yang membolehkan pembagian tidak rata. Sifat memori hasil pemecahan juga dibahas karena menentukan apakah mutasi pada satu bagian terbawa ke array asalnya.
split dengan jumlah bagian rata#
Fungsi np.split(a, n) membagi array a menjadi n bagian dengan panjang yang sama, dan nilai baliknya berupa list berisi array-array bagian. Pembagian hanya mungkin apabila panjang sumbu yang dipecah habis dibagi n. Contoh berikut membagi enam nilai pencatatan suhu menjadi tiga bagian.
import numpy as np
suhu = np.array([24, 26, 25, 27, 28, 26])
bagian = np.split(suhu, 3)
print(bagian)[array([24, 26]), array([25, 27]), array([28, 26])]Hasilnya adalah list berisi tiga array, masing-masing dua elemen, dan tidak ada elemen yang hilang ataupun ganda. Pada array dua dimensi, np.split memecah sumbu pertama secara bawaan, sehingga empat baris terbagi menjadi dua kelompok yang masing-masing dua baris.
import numpy as np
a = np.arange(12).reshape(4, 3)
for b in np.split(a, 2):
print(b)[[0 1 2]
[3 4 5]]
[[ 6 7 8]
[ 9 10 11]]Sumbu pemecahan dapat dipindahkan dengan parameter axis. Dengan axis=1, pemecahan bergerak sepanjang kolom, sehingga array empat baris dan tiga kolom terbagi menjadi tiga array empat baris dan satu kolom.
import numpy as np
a = np.arange(12).reshape(4, 3)
k1, k2, k3 = np.split(a, 3, axis=1)
print(k1)
print(k1.shape, k2.shape, k3.shape)[[0]
[3]
[6]
[9]]
(4, 1) (4, 1) (4, 1)Setiap kolom kini menjadi array tersendiri berbentuk (4, 1), dan jumlah bagian 3 dipilih karena panjang sumbu kolomnya tepat tiga. Apabila jumlah bagian tidak membagi panjang sumbu, error yang muncul dibahas pada bagian pembagian tidak rata.
Selain jumlah bagian, argumen kedua np.split menerima daftar titik potong. Setiap angka pada daftar itu adalah indeks tempat pemotongan dilakukan, sehingga panjang setiap bagian dapat diatur bebas selama totalnya tetap sama dengan panjang array.
import numpy as np
a = np.array([10, 20, 30, 40, 50, 60])
bagian = np.split(a, [2, 5])
print(bagian)[array([10, 20]), array([30, 40, 50]), array([60])]Titik potong 2 dan 5 menghasilkan bagian berukuran 2, 3, dan 1, yaitu elemen 0 sampai 1, elemen 2 sampai 4, dan elemen 5 sampai akhir. Bentuk pemanggilan ini tepat ketika batas antar bagian diketahui dari logika data, misalnya pemisahan catatan berdasarkan indeks hari, dan tidak lagi bergantung pada pembagian yang rata.
hsplit dan vsplit#
Fungsi np.vsplit memecah array secara vertikal, yaitu memotongnya menjadi kelompok baris, sedangkan np.hsplit memecahnya secara horizontal menjadi kelompok kolom. Keduanya adalah bentuk singkat dari np.split dengan axis=0 dan axis=1. Pemisahan nama ini membuat maksud pemotongan terbaca langsung dari fungsinya, tanpa perlu menulis parameter axis.
import numpy as np
a = np.arange(8).reshape(2, 4)
v = np.vsplit(a, 2)
h = np.hsplit(a, 2)
print(v[0])
print(v[1])
print(h[0])
print(h[1])[[0 1 2 3]]
[[4 5 6 7]]
[[0 1]
[4 5]]
[[2 3]
[6 7]]Pemanggilan np.vsplit(a, 2) menghasilkan dua matriks satu baris karena pemotongan bergerak ke bawah, sedangkan np.hsplit(a, 2) menghasilkan dua matriks dua kolom karena pemotongan bergerak ke samping, yaitu kolom 0 dan 1 pada potongan pertama, kemudian kolom 2 dan 3 pada potongan kedua. Kedua fungsi menerima jumlah bagian atau daftar titik potong sebagai argumen keduanya, sama seperti np.split. Contoh di atas menggunakan jumlah bagian, sehingga setiap potongan berukuran sama.
Pembagian tidak rata dan array_split#
Apabila panjang sumbu yang dipecah tidak habis dibagi jumlah bagian, np.split menolak operasinya dengan ValueError. Contoh berikut mencoba membagi sepuluh elemen menjadi tiga bagian, dan sepuluh memang tidak dapat terbagi rata menjadi tiga.
import numpy as np
a = np.arange(10)
try:
np.split(a, 3)
except ValueError as e:
print(f"{type(e).__name__}: {e}")ValueError: array split does not result in an equal divisionPesan array split does not result in an equal division menyatakan penyebabnya secara langsung, tanpa petunjuk tentang banyaknya sisa elemen. Apabila pembagian rata memang tidak mungkin dan sisa elemen masih dapat diterima, fungsi np.array_split menyediakan perilaku yang lebih lunak. Bagian awal menerima satu elemen tambahan sampai seluruh elemen habis terbagi.
import numpy as np
a = np.arange(10)
print(np.array_split(a, 3))[array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8, 9])]Tiga bagian hasilnya berukuran 4, 3, dan 3, dengan bagian yang lebih panjang selalu berada di awal. Fungsi ini berguna ketika panjang data tidak dapat dikendalikan, misalnya membagi seribu catatan ke dalam beberapa kelompok kerja. Perlu diketahui bahwa np.array_split tetap memecah sesuai urutan elemen, sehingga pembagian yang dihasilkannya bersifat tetap dan dapat direproduksi.
Kesalahan umum#
Kesalahan yang mudah terjadi adalah menganggap hasil pemecahan berupa salinan yang berdiri sendiri. Faktanya, np.split menghasilkan view, sehingga setiap bagian berbagi memori dengan array asalnya.
import numpy as np
a = np.arange(6)
b1, b2 = np.split(a, 2)
print(np.shares_memory(a, b1))
b1[0] = 99
print(a[0])True
99Keluaran True menunjukkan bahwa b1 berbagi memori dengan a, dan mutasi b1[0] = 99 terbawa ke a[0]. Perilaku ini hemat memori pada array besar, tetapi berbahaya apabila bagian hasil pemecahan dimodifikasi dengan asumsi data asalnya aman. Panggil .copy() pada setiap bagian yang akan dimutasi apabila array asal harus tetap utuh.
Kesalahan kedua adalah memanggil np.vsplit pada array satu dimensi. Fungsi ini memotong sepanjang sumbu baris, sehingga NumPy menuntut array memiliki setidaknya dua dimensi.
import numpy as np
v = np.arange(6)
try:
np.vsplit(v, 3)
except ValueError as e:
print(f"{type(e).__name__}: {e}")ValueError: vsplit only works on arrays of 2 or more dimensionsPesan error menyatakan syarat tersebut secara harfiah. Apabila data memang satu dimensi, gunakan np.split yang memecah sumbu tunggalnya tanpa syarat dimensi, atau bentuk ulang array dengan reshape terlebih dahulu bila pemotongan baris dan kolom memang dimaksudkan.
Ringkasan#
np.split(a, n)membagi array menjadinbagian rata dan mengembalikan list berisi array bagian, dengan sumbu pemecahan yang dapat dipindahkan melaluiaxis.np.vsplitdannp.hsplitmenyatakan arah pemotongan secara eksplisit, yaitu kelompok baris dan kelompok kolom.- Pembagian yang tidak rata menimbulkan
ValueErrorpadanp.split, sedangkannp.array_splitmembolehkannya dengan menambah sisa elemen ke bagian awal. - Hasil pemecahan berupa view yang berbagi memori dengan array asal, sehingga mutasi pada satu bagian terbawa ke asalnya.
Referensi#
- numpy.split — NumPy — Dokumentasi split beserta syarat pembagian rata dan parameter axis.
- numpy.array_split — NumPy — Dokumentasi pemecahan yang membolehkan bagian tidak rata.