Python

NumPy: Array Computing Python

Tutorial lengkap NumPy untuk komputasi numerik — pembuatan array, operasi matematika, broadcasting, indexing, slicing, dan linear algebra dengan contoh kode praktis

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
KecepatanOperasi NumPy 10-100x lebih cepat dari loop Python biasa karena ditulis dalam C
Memori EfisienMenyimpan data lebih kompak dibanding list Python
VektorisasiOperasi pada seluruh array tanpa perlu loop eksplisit
BroadcastingOperasi antar array dengan ukuran berbeda secara otomatis
Linear AlgebraFungsi lengkap untuk aljabar linear, transformasi, dan dekomposisi
EkosistemMenjadi dasar bagi Pandas, Matplotlib, Scikit-learn, dan banyak lagi

NumPy List vs Python List

Diagram: Perbandingan NumPy Array vs Python List
┌─────────────────────────────────────────────────────────┐
│          PYTHON LIST           │      NUMPY ARRAY       │
│                                │                        │
│  [1, "dua", 3.0, True]        │  [1, 2, 3, 4, 5]      │
│  ▪ Tipe campuran               │  ▪ Tipe seragam        │
│  ▪ Fleksibel tapi lambat       │  ▪ Kaku tapi cepat     │
│  ▪ Pointer-based (boros RAM)   │  ▪ Contiguous memory   │
│  ▪ Loop manual untuk operasi   │  ▪ Operasi vektorisasi  │
│                                │                        │
│  [1,2,3] + [4,5,6]            │  [1,2,3] + [4,5,6]    │
│  = [1,2,3,4,5,6] (gabung)     │  = [5,7,9] (elemen)   │
└─────────────────────────────────────────────────────────┘

2. Instalasi NumPy

NumPy bisa diinstal dengan mudah menggunakan pip atau conda.

Instalasi dengan pip

Terminal — Instalasi
# 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

Terminal — 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

Python — Import
# 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())
💡 Tips

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

Python — Array Dasar
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

Python — Array 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

Python — 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

Python — Operasi Aritmatika
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

Python — Perbandingan
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

Python — 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)

Python — Indexing 2D
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]]
⚠️ Perhatian: View vs Copy

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

Diagram: Aturan Broadcasting NumPy
┌──────────────────────────────────────────────────────────┐
│                ATURAN BROADCASTING                       │
│                                                          │
│  Rule 1: Jika array berbeda jumlah dimensi,              │
│          tambah 1 di depan shape yang lebih kecil        │
│                                                          │
│  Rule 2: Ukuran 1 bisa "ditarik" agar cocok              │
│                                                          │
│  Rule 3: Jika ukuran tidak cocok dan bukan 1, error!     │
│                                                          │
│  Contoh:                                                 │
│    A (3, 4)  +  B (4,)     →  B jadi (1,4) lalu (3,4)   │
│    A (3, 4)  +  C (3, 1)   →  C ditarik jadi (3, 4)     │
│    A (3, 4)  +  D (3,)     →  ERROR! (tidak cocok)      │
└──────────────────────────────────────────────────────────┘

Contoh Broadcasting

Python — 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.

Python — Statistik
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.

Python — Reshape
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.

Python — Linear Algebra
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.

Python — Random
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

Python — Tips NumPy
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]
💡 Tips

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:

Pertanyaan 1: Apa output dari kode berikut? print(np.array([1,2,3]) + np.array([4,5,6]))

a) [1, 2, 3, 4, 5, 6]
b) [5, 7, 9]
c) [[1,4],[2,5],[3,6]]
d) Error

Pertanyaan 2: Apa fungsi dari np.zeros((3, 4))?

a) Membuat array 1D dengan 3 elemen bernilai 4
b) Membuat matriks 3x4 berisi angka nol
c) Membuat array dengan 3 dan 4 sebagai elemen
d) Membuat matriks identitas 3x4

Pertanyaan 3: Apa itu broadcasting dalam NumPy?

a) Mengirim data array ke komputer lain
b) Operasi pada array berbeda ukuran tanpa menyalin data
c) Mengubah tipe data array
d) Menggabungkan beberapa array menjadi satu

Pertanyaan 4: Apa output dari np.arange(0, 10, 2)?

a) [0, 2, 4, 6, 8, 10]
b) [0, 2, 4, 6, 8]
c) [2, 4, 6, 8]
d) [0, 1, 2, 3, 4, 5]

Pertanyaan 5: Method apa yang digunakan untuk menghitung invers matriks di NumPy?

a) np.inverse()
b) np.linalg.inv()
c) np.mat.inv()
d) np.reverse()
🔍 Zoom
100%
🎨 Tema