1. Pengenalan NumPy
NumPy (Numerical Python) adalah library fundamental untuk komputasi numerik di Python. NumPy menyediakan objek array multidimensi yang cepat dan efisien, serta berbagai fungsi matematika untuk operasi pada array tersebut.
NumPy menjadi fondasi bagi hampir semua library data science di Python, termasuk Pandas, Matplotlib, Scikit-learn, TensorFlow, dan PyTorch. Tanpa NumPy, ekosistem data science Python tidak akan sekuat saat ini.
Mengapa Menggunakan NumPy?
| Keunggulan | Penjelasan |
|---|---|
| Kecepatan | Operasi NumPy 10-100x lebih cepat dari loop Python biasa karena ditulis dalam C |
| Memori Efisien | Menyimpan data lebih kompak dibanding list Python |
| Vektorisasi | Operasi pada seluruh array tanpa perlu loop eksplisit |
| Broadcasting | Operasi antar array dengan ukuran berbeda secara otomatis |
| Linear Algebra | Fungsi lengkap untuk aljabar linear, transformasi, dan dekomposisi |
| Ekosistem | Menjadi dasar bagi Pandas, Matplotlib, Scikit-learn, dan banyak lagi |
NumPy List vs Python List
2. Instalasi NumPy
NumPy bisa diinstal dengan mudah menggunakan pip atau conda.
Instalasi dengan pip
# Instal NumPy dengan pip
pip install numpy
# Instal versi spesifik
pip install numpy==1.26.4
# Upgrade ke versi terbaru
pip install --upgrade numpy
# Verifikasi instalasi
python -c "import numpy; print(numpy.__version__)"
# Output: 1.26.4
Instalasi dengan conda
# Instal NumPy dengan conda (Anaconda/Miniconda)
conda install numpy
# Instal di environment tertentu
conda create -n datasci python=3.12 numpy pandas matplotlib
conda activate datasci
Import NumPy
# Konvensi import NumPy — selalu gunakan alias 'np'
import numpy as np
# Cek versi
print(np.__version__) # 1.26.4
# Cek konfigurasi
print(np.show_config())
Selalu gunakan import numpy as np — ini adalah konvensi universal yang diikuti oleh seluruh komunitas data science. Menulis np.array() lebih ringkas daripada numpy.array().
3. Membuat Array
NumPy menyediakan berbagai cara untuk membuat array — dari list Python, dengan nilai konstanta, dengan deret angka, atau dengan distribusi random.
Array dari List Python
import numpy as np
# Array 1D dari list
arr1d = np.array([1, 2, 3, 4, 5])
print(arr1d) # [1 2 3 4 5]
print(type(arr1d)) # <class 'numpy.ndarray'>
# Array 2D (matriks) dari nested list
arr2d = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(arr2d)
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
# Array 3D
arr3d = np.array([[[1, 2], [3, 4]],
[[5, 6], [7, 8]]])
print(arr3d.shape) # (2, 2, 2)
# Menentukan tipe data secara eksplisit
arr_float = np.array([1, 2, 3], dtype=np.float64)
print(arr_float) # [1. 2. 3.]
print(arr_float.dtype) # float64
arr_int = np.array([1.5, 2.7, 3.9], dtype=np.int32)
print(arr_int) # [1 2 3] (dibulatkan ke bawah)
Array dengan Nilai Konstanta
import numpy as np
# Array berisi nol
zeros = np.zeros((3, 4))
print(zeros)
# [[0. 0. 0. 0.]
# [0. 0. 0. 0.]
# [0. 0. 0. 0.]]
# Array berisi satu
ones = np.ones((2, 3))
print(ones)
# [[1. 1. 1.]
# [1. 1. 1.]]
# Array berisi nilai tertentu
full_arr = np.full((2, 3), 7)
print(full_arr)
# [[7 7 7]
# [7 7 7]]
# Matriks identitas
eye = np.eye(4)
print(eye)
# [[1. 0. 0. 0.]
# [0. 1. 0. 0.]
# [0. 0. 1. 0.]
# [0. 0. 0. 1.]]
# Array kosong (nilai random di memori)
empty = np.empty((2, 2))
print(empty) # Nilai tidak terdefinisi
Array dengan Deret Angka
import numpy as np
# Arange — seperti range() tapi menghasilkan array
arr_range = np.arange(0, 10, 2)
print(arr_range) # [0 2 4 6 8]
# Linspace — N titik yang terdistribusi merata
arr_lin = np.linspace(0, 1, 5)
print(arr_lin) # [0. 0.25 0.5 0.75 1. ]
# Logspace — titik pada skala logaritmik
arr_log = np.logspace(1, 3, 4)
print(arr_log) # [ 10. 46.42 215.44 1000. ]
# Membuat array dengan step tertentu
arr_step = np.arange(0, 1, 0.1)
print(arr_step)
# [0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
4. Operasi Array
Keunggulan utama NumPy adalah operasi vektorisasi — operasi dilakukan pada seluruh elemen array sekaligus tanpa perlu loop. Ini jauh lebih cepat dari loop Python biasa.
Aritmatika Element-wise
import numpy as np
a = np.array([10, 20, 30, 40])
b = np.array([1, 2, 3, 4])
# Operasi element-wise (per elemen)
print(a + b) # [11 22 33 44] — penjumlahan
print(a - b) # [ 9 18 27 36] — pengurangan
print(a * b) # [ 10 40 90 160] — perkalian
print(a / b) # [10. 10. 10. 10.] — pembagian
print(a ** b) # [ 10 400 27000 2560000] — pangkat
print(a % b) # [0 0 0 0] — modulus
# Operasi dengan skalar (scalar)
print(a + 5) # [15 25 35 45]
print(a * 2) # [20 40 60 80]
print(a / 10) # [1. 2. 3. 4.]
# Operasi matematika universal (ufunc)
print(np.sqrt(a)) # [3.16 4.47 5.48 6.32] — akar kuadrat
print(np.exp(a)) # Eksponensial
print(np.log(a)) # Logaritma natural
print(np.sin(a)) # Sinus
print(np.abs(-a)) # [10 20 30 40] — nilai absolut
Perbandingan dan Logika
import numpy as np
a = np.array([1, 5, 10, 15, 20])
# Perbandingan — menghasilkan boolean array
print(a > 10) # [False False False True True]
print(a == 5) # [False True False False False]
print(a != 1) # [False True True True True]
# Boolean indexing — filter array
mask = a > 10
print(a[mask]) # [15 20]
# Kondisi logika
print(np.logical_and(a > 5, a < 20)) # [False False True True False]
print(np.logical_or(a < 3, a > 18)) # [ True False False False True]
# np.where — seperti ternary untuk array
hasil = np.where(a > 10, "besar", "kecil")
print(hasil) # ['kecil' 'kecil' 'kecil' 'besar' 'besar']
5. Indexing dan Slicing
NumPy memperluas konsep indexing dan slicing Python ke dimensi yang lebih tinggi. Anda bisa mengakses, mengubah, dan memfilter elemen array dengan sangat fleksibel.
Indexing 1D
import numpy as np
arr = np.array([10, 20, 30, 40, 50, 60, 70])
# Index positif (dari depan)
print(arr[0]) # 10
print(arr[3]) # 40
# Index negatif (dari belakang)
print(arr[-1]) # 70
print(arr[-3]) # 50
# Slicing [start:stop:step]
print(arr[1:5]) # [20 30 40 50]
print(arr[::2]) # [10 30 50 70] — setiap 2 elemen
print(arr[::-1]) # [70 60 50 40 30 20 10] — balik urutan
# Mengubah elemen dengan slicing
arr[0:3] = 99
print(arr) # [99 99 99 40 50 60 70]
Indexing 2D (Matriks)
import numpy as np
matriks = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
# Akses elemen: [baris, kolom]
print(matriks[0, 0]) # 1 (baris 0, kolom 0)
print(matriks[1, 2]) # 7 (baris 1, kolom 2)
print(matriks[-1, -1]) # 12 (baris terakhir, kolom terakhir)
# Slicing baris dan kolom
print(matriks[0, :]) # [1 2 3 4] — seluruh baris 0
print(matriks[:, 1]) # [ 2 6 10] — seluruh kolom 1
print(matriks[0:2, 1:3]) # [[2 3] [6 7]] — sub-matriks
# Boolean indexing pada 2D
print(matriks[matriks > 6]) # [ 7 8 9 10 11 12]
# Fancy indexing — akses dengan list index
print(matriks[[0, 2], :]) # Baris 0 dan 2
# [[ 1 2 3 4]
# [ 9 10 11 12]]
Slicing di NumPy menghasilkan view (referensi), bukan copy. Mengubah slice akan mengubah array asli! Gunakan arr.copy() jika ingin membuat salinan independen.
6. Broadcasting
Broadcasting adalah mekanisme NumPy untuk melakukan operasi pada array dengan ukuran berbeda tanpa perlu menyalin data. NumPy akan secara otomatis "menyiarkan" array yang lebih kecil agar sesuai dengan array yang lebih besar.
Aturan Broadcasting
Contoh Broadcasting
import numpy as np
# Broadcasting skalar ke array
arr = np.array([[1, 2, 3],
[4, 5, 6]])
print(arr + 10)
# [[11 12 13]
# [14 15 16]]
# Broadcasting vektor baris ke matriks
arr2d = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
row = np.array([10, 20, 30])
print(arr2d + row)
# [[11 22 33]
# [14 25 36]
# [17 28 39]]
# Broadcasting vektor kolom ke matriks
col = np.array([[100], [200], [300]])
print(arr2d + col)
# [[101 102 103]
# [204 205 206]
# [307 308 309]]
# Normalisasi data dengan broadcasting
data = np.array([[85, 90, 78],
[92, 88, 95],
[76, 82, 80]])
mean = data.mean(axis=0) # Rata-rata per kolom
std = data.std(axis=0) # Standar deviasi per kolom
normalized = (data - mean) / std
print(normalized)
# Data terstandarisasi (mean=0, std=1 per kolom)
7. Fungsi Statistik
NumPy menyediakan fungsi statistik lengkap yang bisa diterapkan pada seluruh array atau sepanjang axis tertentu.
import numpy as np
data = np.array([[85, 90, 78],
[92, 88, 95],
[76, 82, 80],
[90, 95, 88]])
# Statistik dasar
print(np.mean(data)) # 86.17 — rata-rata keseluruhan
print(np.median(data)) # 86.5 — median
print(np.std(data)) # 6.27 — standar deviasi
print(np.var(data)) # 39.31 — varians
print(np.min(data)) # 76 — nilai minimum
print(np.max(data)) # 95 — nilai maximum
print(np.sum(data)) # 1034 — total
# Statistik per axis
# axis=0 → operasi sepanjang baris (hasil per kolom)
# axis=1 → operasi sepanjang kolom (hasil per baris)
print(np.mean(data, axis=0)) # [85.75 88.75 85.25]
print(np.mean(data, axis=1)) # [84.33 91.67 79.33 91. ]
print(np.max(data, axis=1)) # [90 95 82 95]
# Kumulatif
print(np.cumsum([1, 2, 3, 4])) # [ 1 3 6 10] — jumlah kumulatif
print(np.cumprod([1, 2, 3, 4])) # [ 1 2 6 24] — perkalian kumulatif
# Persentil dan kuartil
print(np.percentile(data, 50)) # 86.5 (sama dengan median)
print(np.percentile(data, [25, 50, 75])) # [81. 86.5 91. ]
8. Reshaping dan Manipulasi
NumPy memungkinkan Anda mengubah bentuk (shape) array tanpa mengubah datanya. Ini sangat berguna saat mempersiapkan data untuk machine learning atau visualisasi.
import numpy as np
# Reshape array
arr = np.arange(12)
print(arr) # [ 0 1 2 3 4 5 6 7 8 9 10 11]
# Reshape ke 3x4
reshaped = arr.reshape(3, 4)
print(reshaped)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
# Reshape ke 4x3
print(arr.reshape(4, 3))
# [[ 0 1 2]
# [ 3 4 5]
# [ 6 7 8]
# [ 9 10 11]]
# Gunakan -1 agar NumPy menghitung otomatis
print(arr.reshape(2, -1)) # 2 baris, kolom dihitung → (2, 6)
print(arr.reshape(-1, 6)) # baris dihitung, 6 kolom → (2, 6)
# Flatten — ratakan ke 1D
flat = reshaped.flatten()
print(flat) # [ 0 1 2 3 4 5 6 7 8 9 10 11]
# Transpose — tukar baris dan kolom
print(reshaped.T)
# [[ 0 4 8]
# [ 1 5 9]
# [ 2 6 10]
# [ 3 7 11]]
# Stack — gabungkan array
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print(np.vstack([a, b])) # Vertical stack
# [[1 2 3]
# [4 5 6]]
print(np.hstack([a, b])) # Horizontal stack
# [1 2 3 4 5 6]
# Split — pisahkan array
arr = np.arange(9).reshape(3, 3)
print(np.vsplit(arr, 3)) # Split jadi 3 bagian (baris)
print(np.hsplit(arr, 3)) # Split jadi 3 bagian (kolom)
9. Linear Algebra
NumPy memiliki modul numpy.linalg yang menyediakan fungsi aljabar linear lengkap — perkalian matriks, determinan, invers, dekomposisi, dan lainnya.
import numpy as np
A = np.array([[1, 2],
[3, 4]])
B = np.array([[5, 6],
[7, 8]])
# Perkalian matriks (dot product)
print(np.dot(A, B))
# [[19 22]
# [43 50]]
# Atau gunakan @ operator (Python 3.5+)
print(A @ B)
# [[19 22]
# [43 50]]
# Perkalian element-wise (bukan dot product!)
print(A * B)
# [[ 5 12]
# [21 32]]
# Transpose
print(A.T)
# [[1 3]
# [2 4]]
# Determinan
det = np.linalg.det(A)
print(f"Determinan: {det:.2f}") # Determinan: -2.00
# Invers matriks
inv_A = np.linalg.inv(A)
print(inv_A)
# [[-2. 1. ]
# [ 1.5 -0.5]]
# Verifikasi: A * A_inv = Identity
print(np.round(A @ inv_A, 10))
# [[1. 0.]
# [0. 1.]]
# Eigenvalues dan eigenvectors
eigenvalues, eigenvectors = np.linalg.eig(A)
print(f"Eigenvalues: {eigenvalues}")
print(f"Eigenvectors:\n{eigenvectors}")
# Sistem persamaan linear: Ax = b
# 2x + 3y = 8
# 4x + 5y = 14
A_eq = np.array([[2, 3], [4, 5]])
b_eq = np.array([8, 14])
x = np.linalg.solve(A_eq, b_eq)
print(f"Solusi: x={x[0]}, y={x[1]}") # x=1.0, y=2.0
# Norm (panjang vektor)
v = np.array([3, 4])
print(np.linalg.norm(v)) # 5.0 (Euclidean norm)
print(np.linalg.norm(v, 1)) # 7.0 (L1 norm / Manhattan)
10. Random Number Generation
Modul numpy.random menyediakan generator angka acak yang cepat dan kaya fitur — sangat penting untuk simulasi, sampling, dan inisialisasi model machine learning.
import numpy as np
# Set seed untuk reproducibility
np.random.seed(42)
# Random float antara 0 dan 1
print(np.random.rand(3)) # 3 angka random
print(np.random.rand(2, 3)) # Matriks 2x3
# Random integer
print(np.random.randint(1, 100, size=5)) # 5 angka 1-99
print(np.random.randint(1, 10, size=(3, 3))) # Matriks 3x3
# Distribusi normal (Gaussian)
normal = np.random.randn(1000) # mean=0, std=1
print(f"Mean: {normal.mean():.2f}") # ≈ 0
print(f"Std: {normal.std():.2f}") # ≈ 1
# Distribusi normal dengan mean dan std tertentu
nilai_ujian = np.random.normal(loc=75, scale=10, size=1000)
print(f"Rata-rata: {nilai_ujian.mean():.2f}") # ≈ 75
print(f"Std: {nilai_ujian.std():.2f}") # ≈ 10
# Pilihan random dari array
buah = ["apel", "mangga", "jeruk", "pisang", "anggur"]
pilihan = np.random.choice(buah, size=10, replace=True)
print(pilihan) # 10 buah random (boleh duplikat)
# Shuffle array (in-place)
arr = np.arange(10)
np.random.shuffle(arr)
print(arr) # Acak!
# Permutasi (mengembalikan array baru)
arr2 = np.arange(10)
print(np.random.permutation(arr2)) # Array baru yang diacak
11. Tips dan Trik NumPy
Praktik Terbaik
import numpy as np
# 1. Hindari loop — gunakan vektorisasi
# ❌ Lambat
arr = np.arange(1000000)
hasil_slow = []
for x in arr:
hasil_slow.append(x ** 2)
# ✅ Cepat (100x lebih cepat)
hasil_fast = arr ** 2
# 2. Gunakan .shape dan .dtype untuk inspeksi
data = np.random.randn(100, 5)
print(f"Shape: {data.shape}") # (100, 5)
print(f"Dtype: {data.dtype}") # float64
print(f"Size: {data.size}") # 500
print(f"NDim: {data.ndim}") # 2
# 3. Gunakan dtype hemat memori
big_arr = np.arange(1000000, dtype=np.float32) # 4 byte/elem
small_arr = np.arange(1000000, dtype=np.float64) # 8 byte/elem
print(f"Float32: {big_arr.nbytes / 1e6:.1f} MB") # 4.0 MB
print(f"Float64: {small_arr.nbytes / 1e6:.1f} MB") # 8.0 MB
# 4. np.where untuk conditional replacement
arr = np.array([1, -2, 3, -4, 5])
cleaned = np.where(arr < 0, 0, arr)
print(cleaned) # [1 0 3 0 5]
# 5. np.unique — ambil nilai unik
data = np.array([1, 2, 2, 3, 3, 3, 4])
unik, counts = np.unique(data, return_counts=True)
print(f"Unik: {unik}") # [1 2 3 4]
print(f"Counts: {counts}") # [1 2 3 1]
Selalu gunakan vektorisasi NumPy alih-alih loop Python. Perbandingan kecepatan: untuk array 1 juta elemen, loop Python butuh ~500ms, sedangkan operasi NumPy hanya ~5ms — 100x lebih cepat!
12. Quiz: Uji Pemahamanmu!
Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang NumPy: