Laporan penjualan biasanya tidak berhenti pada angka total. Pemilik toko ingin tahu bagaimana total itu terbentuk: berapa akumulasi omzet sampai hari ketiga, pada hari keberapa kas melewati satu juta rupiah, dan seberapa cepat akumulasi tersebut tumbuh dari bulan ke bulan. NumPy menjawab kebutuhan semacam ini dengan dua fungsi akumulasi: np.cumsum untuk penjumlahan berjalan dan np.cumprod untuk perkalian berjalan.
Berbeda dengan np.sum yang menciutkan seluruh array menjadi satu angka, cumsum dan cumprod menghasilkan array baru yang bentuknya sama dengan input. Setiap elemen hasil menyimpan akumulasi dari elemen pertama hingga posisi tersebut. Bab ini membahas mekanisme kedua fungsi, penggunaan axis pada array 2-D, serta perbedaan bentuk hasil antara agregasi dan akumulasi.
Dari sum ke Akumulasi Berjalan #
Secara matematis, elemen ke-i dari np.cumsum(a) adalah a[0] + a[1] + ... + a[i]. Tidak ada elemen yang dibuang; setiap tahap penjumlahan justru disimpan sebagai hasil. Mari kita bandingkan langsung dengan np.sum pada data setoran kasir harian:
import numpy as np
setoran = np.array([150, 200, 120, 180, 250]) # ribu rupiah per hari
total = np.sum(setoran)
saldo = np.cumsum(setoran)
print("total :", total)
print("saldo :", saldo)
print("shape total:", total.shape)
print("shape saldo:", saldo.shape)
print("saldo akhir == total:", saldo[-1] == total)Output yang Dihasilkan:
total : 900
saldo : [150 350 470 650 900]
shape total: ()
shape saldo: (5,)
saldo akhir == total: TrueMari kita bedah apa yang dilakukan interpreter pada kode di atas:
- Baris 3 (
np.array(...)): interpreter membuat array 1-D bertipeint64dengan lima elemen setoran harian dalam ribu rupiah. - Baris 5 (
np.sum(setoran)): seluruh elemen diringkas menjadi satu nilai skalar900dengan bentuk(). - Baris 6 (
np.cumsum(setoran)): menghasilkan array lima elemen; elemen ke-0 adalah150, elemen ke-1 adalah150 + 200 = 350, dan seterusnya hingga900. - Baris 10-11 (
total.shape,saldo.shape): perbandingan bentuk memperlihatkan perbedaan mendasar — agregasi menciutkan ke(), akumulasi mempertahankan(5,). - Baris 12 (
saldo[-1] == total): elemen terakhir hasilcumsumselalu sama dengan total; identitas ini berguna sebagai pemeriksa cepat kebenaran perhitungan.
cumprod untuk Pertumbuhan Berantai #
Pertumbuhan persentase tidak boleh dijumlahkan, melainkan dikalikan. Kenaikan 5% dinyatakan sebagai faktor 1.05 dan penurunan 2% sebagai faktor 0.98. Untuk melacak indeks berjalan dari serangkaian faktor tersebut, kita memakai np.cumprod:
import numpy as np
faktor_bulanan = np.array([1.0, 1.05, 1.05, 0.98, 1.02])
indeks = np.cumprod(faktor_bulanan)
print("faktor :", faktor_bulanan)
print("indeks :", indeks)
print("indeks akhir:", indeks[-1])Output yang Dihasilkan:
faktor : [1. 1.05 1.05 0.98 1.02]
indeks : [1. 1.05 1.1025 1.08045 1.102059]
indeks akhir: 1.102059Tiga hal yang perlu kita amati:
- Baris 3: array faktor pengali bulanan; bulan pertama menjadi acuan sehingga faktornya
1.0. - Baris 5 (
np.cumprod(...)): akumulasi perkalian berjalan —1.0, lalu1.05, lalu1.05 × 1.05 = 1.1025, lalu1.1025 × 0.98 = 1.08045, dan terakhir1.08045 × 1.02 = 1.102059. - Baris 9: elemen terakhir adalah faktor pengali total lima bulan; penjualan akhir bulan kelima setara dengan kenaikan sekitar 10,2% dibanding bulan acuan.
Akumulasi pada Array 2-D dengan axis #
Sama seperti fungsi agregasi lain, cumsum menerima parameter axis. Arah axis menentukan sepanjang garis mana akumulasi dijalankan: axis=0 mengakumulasi ke bawah (antar baris dalam satu kolom), sedangkan axis=1 mengakumulasi ke kanan (antar kolom dalam satu baris). Tanpa axis, array diratakan menjadi 1-D terlebih dahulu:
import numpy as np
penjualan = np.array([
[50, 65, 40],
[70, 55, 80],
[45, 60, 75],
]) # baris: cabang, kolom: hari
print("axis=0 (akumulasi ke bawah):")
print(np.cumsum(penjualan, axis=0))
print("axis=1 (akumulasi ke kanan):")
print(np.cumsum(penjualan, axis=1))
print("tanpa axis (diratakan):")
print(np.cumsum(penjualan))Output yang Dihasilkan:
axis=0 (akumulasi ke bawah):
[[ 50 65 40]
[120 120 120]
[165 180 195]]
axis=1 (akumulasi ke kanan):
[[ 50 115 155]
[ 70 125 205]
[ 45 105 180]]
tanpa axis (diratakan):
[ 50 115 155 225 280 360 405 465 540]Pada axis=0, baris kedua hasil adalah penjumlahan baris pertama dan kedua data (120 = 50 + 70 untuk kolom pertama), dan baris ketiga hasil menumpuk tiga baris data (165 = 50 + 70 + 45). Pada axis=1, kolom kedua hasil adalah penjumlahan dua kolom pertama data per baris (115 = 50 + 65). Versi tanpa axis meratakan sembilan elemen mengikuti urutan C, lalu mengakumulasi semuanya menjadi array (9,). Semantik axis yang lebih umum sudah dibahas pada Chapter Operasi Berdasarkan Axis.
Sebagai penutup, tabel berikut merangkum perbedaan fungsi agregasi dan akumulasi yang kita pakai sejak Chapter sum dan prod:
| Fungsi | Pertanyaan yang dijawab | Bentuk hasil |
|---|---|---|
np.sum | Berapa total seluruh elemen? | menciutkan (skalar untuk 1-D) |
np.prod | Berapa hasil kali seluruh elemen? | menciutkan (skalar untuk 1-D) |
np.cumsum | Berapa total berjalan sampai titik ini? | sama dengan input |
np.cumprod | Berapa perkalian berjalan sampai titik ini? | sama dengan input |