DataLens

Agregasi (sum, mean, dan argumen axis)

Rangkum array secara keseluruhan, per baris atau per kolom, temukan di mana nilai maksimumnya, dan tangani nilai yang hilang.

Level: Menengah · 8 menit baca

Latihan modul ini

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

Idenya

Agregasi mengubah banyak angka menjadi lebih sedikit: total, rata-rata, maksimum. Pada array 1-D hasilnya satu angka. Pada grid 2-D kamu punya pilihan: rangkum semuanya, setiap baris, atau setiap kolom. Argumen axis menentukan pilihan itu, dan begitu kamu paham, satu keluarga pertanyaan menjadi satu baris pendek.

import numpy as np

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],
])

Seluruh array

Mulai dari kasus paling sederhana, merangkum setiap angka di grid. Berapa total unit yang dijual keempat toko selama enam bulan, dan berapa angka bulanan terkecil dan terbesar dari toko mana pun?

print(units.sum(), units.mean(), units.min(), units.max())
print(units.std().round(1))
2338 97.41666666666667 40 170
37.4

Setiap method punya kembaran berbentuk fungsi: units.sum() sama dengan np.sum(units). Beberapa yang berguna hanya ada sebagai fungsi, seperti np.median dan np.percentile:

print(np.median(units), np.percentile(units, 90))
95.0 153.5

Argumen axis

axis menyatakan dimensi mana yang diremas:

print(units.sum(axis=0))   # total per bulan
print(units.sum(axis=1))   # total per toko
[335 357 388 408 410 440]
[890 538 625 285]
Ide utama

axis=0 ↓ (turun melewati baris, hasil per kolom). axis=1 → (melintang melewati kolom, hasil per baris). Axis yang kamu sebut adalah yang menghilang: (4, 6) yang dijumlahkan atas axis 0 menjadi (6,); atas axis 1 menjadi (4,).

Setiap agregasi menerima axis:

print(units.mean(axis=1).round(1))   # rata-rata bulan per toko
print(units.max(axis=0))             # unit toko terbaik di setiap bulan
[148.3  89.7 104.2  47.5]
[120 135 150 160 155 170]

Di mana maksimumnya? argmax dan argmin

.max() memberi nilai terbesar; .argmax() memberi posisinya. Digabung dengan list labelmu, itu menjawab "yang mana?":

print(units.argmax(axis=1))     # posisi bulan terbaik setiap toko

weakest = units.argmin(axis=1)  # posisi bulan terlemah setiap toko
for store, m in zip(stores, weakest):
    print(f"{store}: weakest month {months[m]}")
[5 5 5 5]
Jakarta: weakest month Jan
Bandung: weakest month Jan
Surabaya: weakest month Feb
Medan: weakest month Jan

Setiap toko mencapai puncaknya di bulan Juni (posisi 5), tanda pertumbuhan yang stabil. Bulan terlemah mereka berbeda-beda. Loop di sini hanya memformat output; perhitungannya sendiri adalah satu pemanggilan tervektorisasi. Kamu bahkan bisa melewatkan loop-nya dengan fancy indexing: np.array(months)[weakest].

Porsi dari total: keepdims

Berapa porsi yang disumbangkan setiap bulan terhadap setengah tahun setiap toko? Bagi setiap baris dengan totalnya sendiri. Tapi units.sum(axis=1) ber-shape (4,), yang tidak bisa di-broadcast terhadap (4, 6) per baris (kamu sudah melihat error itu di modul sebelumnya). keepdims=True mempertahankan axis yang diremas dengan ukuran 1:

totals = units.sum(axis=1, keepdims=True)
print(totals.shape)
share = units / totals
print((share * 100).round(1))
(4, 1)
[[13.5 15.2 16.9 18.  17.4 19.1]
 [14.9 15.8 16.7 16.4 17.7 18.6]
 [15.2 14.7 16.8 17.6 17.3 18.4]
 [14.  15.8 15.1 17.5 18.2 19.3]]

Dengan shape (4, 1), total-nya di-broadcast ke setiap baris. Setiap baris sekarang berjumlah 100%.

Total berjalan: cumsum

cumsum memberi total berjalan di sepanjang sebuah axis, versi NumPy dari kolom kumulatif di Excel:

cumulative = units.cumsum(axis=1)
print(cumulative)
[[120 255 405 565 720 890]
 [ 80 165 255 343 438 538]
 [ 95 187 292 402 510 625]
 [ 40  85 128 178 230 285]]

Gabungkan dengan mask dan argmax untuk menjawab "di bulan apa setiap toko melewati 400 unit?":

passed = cumulative >= 400
print(passed.argmax(axis=1))
[2 4 3 0]

argmax pada boolean mengembalikan posisi True yang pertama. Hati-hati: kalau sebuah baris sama sekali tidak punya True (Medan tidak pernah mencapai 400 di rentang ini), argmax mengembalikan 0, yang terlihat seperti "Januari". Periksa dengan passed.any(axis=1) sebelum memercayai jawabannya:

print(passed.any(axis=1))
[ True  True  True False]

Nilai yang hilang: fungsi yang sadar nan

Data sungguhan punya celah. Pelanggan yang tidak memberi rating tidak punya rating, dan NumPy mewakilinya dengan np.nan, yang berarti "bukan angka". Masalahnya, nan menular: perhitungan biasa apa pun yang menyentuhnya ikut menjadi nan, jadi satu rating yang hilang merusak rata-ratanya:

ratings = np.array([4.5, 5.0, np.nan, 3.5, 4.0])
print(ratings.mean())
print(np.nanmean(ratings), np.nansum(ratings), np.nanmax(ratings))
nan
4.25 17.0 5.0

np.nanmean, np.nansum, np.nanmax dan kawan-kawannya melewati nilai yang hilang, seperti AVG di SQL dan .mean() default di pandas.

Mengapa ini penting untuk kode yang bersih

units.sum(axis=1) menggantikan loop yang membangun list total, dan menyatakan dengan tepat apa yang dihitungnya: total per toko. Beri nama hasilnya sesuai isinya (store_totals, best_month), pakai keepdims=True saat kamu akan membagi dengannya, dan lindungi argmax pada mask dengan .any(). Kebiasaan kecil ini mencegah jawaban salah yang senyap, yang paling sulit ditangkap.

Rangkuman

Latihan modul ini

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

Berikutnya: Reshaping, stacking, dan splitting →