DataLens

Indexing dan slicing

Ambil satu nilai, rentang, baris, kolom dan sub-grid dari array, dan ubah nilainya langsung di tempat.

Level: Dasar · 8 menit baca

Latihan modul ini

Soal-soal untuk pelajaran ini berjalan di browser-mu dan langsung mengecek jawabanmu.

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]
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]]
Ide utama

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

Latihan modul ini

Soal-soal untuk pelajaran ini berjalan di browser-mu dan langsung mengecek jawabanmu.

Berikutnya: Boolean indexing dan fancy indexing →