Idenya
Sebagian besar pertanyaan menyangkut sebagian datamu: minggu lalu, toko Bandung, bulan Maret, tiga produk pertama. Indexing dan slicing adalah cara menunjuk bagian-bagian itu. Kalau kamu tahu slicing list Python, array 1-D bekerja dengan cara yang sama; array 2-D menambahkan satu ide yang ampuh: koma di antara bagian baris dan bagian kolom.
1-D: seperti list
Ini jumlah order harian selama dua minggu dalam satu array. Mengambil satu hari, atau rentang beberapa hari, bekerja persis seperti pada list Python:
import numpy as np
daily_orders = np.array([42, 38, 51, 47, 60, 75, 68, 44, 39, 55, 49, 63, 80, 71])
print(daily_orders[0]) # hari pertama
print(daily_orders[-1]) # hari terakhir
print(daily_orders[2:5]) # hari 3, 4, 5 (index 2 sampai, tapi tidak termasuk, 5)
42
71
[51 47 60]
- Index dimulai dari 0; index negatif menghitung dari belakang.
start:stopmengikutsertakanstartdan tidak mengikutsertakanstop.- Kosongkan salah satu sisi untuk sampai ke ujungnya:
print(daily_orders[:7]) # minggu pertama
print(daily_orders[7:]) # minggu kedua
print(daily_orders[-3:]) # tiga hari terakhir
[42 38 51 47 60 75 68]
[44 39 55 49 63 80 71]
[63 80 71]
Angka ketiga adalah langkah (step):
print(daily_orders[::7]) # setiap hari ke-7: setiap Senin
print(daily_orders[::-1]) # dibalik
[42 44]
[71 80 63 49 55 39 44 68 75 60 47 51 38 42]
2-D: baris dan kolom
Dengan tabel, satu posisi tidak cukup untuk menunjuk sebuah nilai: kamu harus menyebutkan baris dan kolomnya. Di sini barisnya adalah empat toko dan kolomnya enam bulan. Untuk mendapat unit Bandung di bulan Maret, berikan nomor baris dan nomor kolomnya, dipisahkan koma:
stores = ["Jakarta", "Bandung", "Surabaya", "Medan"]
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
units = np.array([
[120, 135, 150, 160, 155, 170],
[ 80, 85, 90, 88, 95, 100],
[ 95, 92, 105, 110, 108, 115],
[ 40, 45, 43, 50, 52, 55],
])
print(units[1, 2]) # baris 1 (Bandung), kolom 2 (Mar)
90
units[row, column], dengan koma. (Kamu juga akan melihat units[1][2], yang berfungsi tapi lebih lambat dan tidak bisa dipakai untuk slice, jadi utamakan koma.)
Setiap sisi koma bisa berupa slice. : sendirian berarti "semua":
print(units[0]) # baris 0: Jakarta, semua bulan
print(units[:, 0]) # semua baris, kolom 0: setiap toko di bulan Januari
print(units[:2, -3:]) # dua toko pertama, tiga bulan terakhir
[120 135 150 160 155 170]
[120 80 95 40]
[[160 155 170]
[ 88 95 100]]
Baca units[rows, columns] sebagai "baris yang mana, koma, kolom yang mana". units[:, 0] berarti "semua baris, kolom 0", satu kolom utuh. Ini ide yang sama dengan yang dipakai pandas di df.iloc[rows, columns].
Melakukan slice pada grid menghasilkan grid yang lebih kecil, dengan shape-nya sendiri:
q2 = units[:, 3:] # April sampai Juni
print(q2.shape)
print(q2.sum())
(4, 3)
1258
Memakai nama untuk menemukan posisi
Array tidak punya label seperti pandas. Simpan labelnya di sebuah list dan cari posisinya dengan .index():
b = stores.index("Bandung")
m = months.index("May")
print(stores[b], months[m], units[b, m])
Bandung May 95
Itulah salah satu alasan pandas ada: ia menjaga label tetap menempel. NumPy adalah lapisan di bawahnya yang lebih cepat dan lebih sederhana.
Mengubah nilai
Assign ke sebuah index atau slice untuk mengubah array langsung di tempat:
units[3, 5] = 58 # koreksi satu nilai
units[2, :2] = [97, 94] # koreksi dua nilai
units[3, :] = 0 # toko Medan tutup: nolkan seluruh barisnya
print(units)
[[120 135 150 160 155 170]
[ 80 85 90 88 95 100]
[ 97 94 105 110 108 115]
[ 0 0 0 0 0 0]]
Meng-assign satu nilai ke sebuah slice mengisi setiap posisinya (= 0 di atas). Meng-assign sebuah array membutuhkan shape yang cocok.
Slice adalah view
Ada satu perbedaan dengan list yang sangat penting. Slicing list membuat salinan; slicing array membuat view: jendela ke data yang sama. Ubah view-nya dan aslinya ikut berubah:
prices = np.array([185, 320, 95, 65, 110])
cheap = prices[2:4]
cheap[0] = 0
print(prices)
[185 320 0 65 110]
View membuat slicing instan bahkan pada array yang sangat besar (tidak ada data yang disalin), tapi sering mengejutkan orang. Saat kamu ingin salinan yang independen, nyatakan dengan .copy(): cheap = prices[2:4].copy(). Modul selanjutnya membahas view dan copy secara mendalam.
Mengapa ini penting untuk kode yang bersih
Index adalah "angka ajaib" yang mudah salah: kolom 2 itu Maret atau April? Kode NumPy yang bersih menyimpan labelnya di dekatnya (months.index("Mar")) atau memberi nama pada slice (q2 = units[:, 3:]), supaya maksudnya terbaca. Dan pakai .copy() setiap kali kamu berencana mengubah sebuah slice tapi ingin aslinya tetap utuh.
Rangkuman
- 1-D:
a[i],a[-1],a[start:stop:step]; stop tidak ikut. - 2-D:
a[row, col]; setiap sisi bisa berupa slice;:berarti semua.a[:, j]adalah kolomj. - Slicing pada grid mengembalikan grid yang lebih kecil dengan
.shape-nya sendiri. - Assign ke index dan slice untuk mengubah nilai di tempat.
- Slice array adalah view dari data yang sama; pakai
.copy()untuk salinan yang independen.