Data hasil perhitungan sering keluar dari batas wajar: operasi pencahayaan bisa mendorong nilai piksel melewati 255, sensor suhu bisa mencatat angka di bawah batas terendah alat, dan hasil model bisa keluar dari rentang yang diminta. Teknik pembatasan ini disebut clamping (menjepit nilai ke dalam rentang), dan di NumPy satu fungsi menangani semuanya: np.clip.

Beberapa contoh penggunaannya:

  • Menjaga nilai piksel gambar tetap pada rentang 0-255 setelah operasi kecerahan.
  • Membatasi persentase diskon agar tidak melewati 0-100.
  • Menahan keluaran model agar berada di dalam rentang kalibrasi sensor.

Dasar np.clip: Menjepit ke Rentang Minimum-Maksimum #

np.clip(a, a_min, a_max) memeriksa setiap elemen: nilai di bawah a_min diganti a_min, nilai di atas a_max diganti a_max, dan nilai di dalam rentang dibiarkan utuh. Contoh klasiknya adalah peningkatan kecerahan gambar 8-bit yang tidak boleh keluar dari rentang 0-255:

python
import numpy as np

pixel = np.array([80, 120, 200, 240])
kecerahan = np.clip(pixel + 50, 0, 255)
print(kecerahan)
rentang = np.array([-20, 5, 90, 130, 300])
print(np.clip(rentang, 0, 255))

Output yang Dihasilkan:

text
[130 170 250 255]
[  0   5  90 130 255]

Mari kita bedah:

  1. Baris 3 (pixel + 50): penjumlahan ufunc menghasilkan array sementara [130, 170, 250, 290] — piksel terakhir melewati batas 255.
  2. Baris 4 (np.clip(..., 0, 255)): nilai 290 dijepit turun menjadi 255; tanpa clip, nilai tersebut tidak valid untuk gambar 8-bit.
  3. Baris 7 (np.clip(rentang, 0, 255)): -20 diangkat ke 0 dan 300 diturunkan ke 255, sementara tiga nilai tengah tidak tersentuh.

Perlu diketahui, np.clip mengembalikan array baru dan tidak mengubah array input; dtype keluarannya mengikuti dtype input, sehingga array integer tetap integer setelah dijepit. Bila hasil ingin ditulis ke buffer yang sudah ada, gunakan parameter out untuk menghindari alokasi tambahan.

Satu Batas Saja dengan None #

Sering kali hanya satu sisi yang perlu dijaga. Isi a_min atau a_max dengan None untuk menonaktifkan batas pada sisi tersebut:

python
import numpy as np

suhu = np.array([-8.0, 12.5, 31.0, 45.5])
print(np.clip(suhu, a_min=None, a_max=40.0))
print(np.clip(suhu, a_min=0.0, a_max=None))

Output yang Dihasilkan:

text
[-8.  12.5 31.  40. ]
[ 0.  12.5 31.  45.5]

Baris pertama hanya menjepit batas atas 40.0, sehingga -8.0 lolos tanpa diubah. Baris kedua hanya menjaga batas bawah 0.0, sehingga 45.5 tetap dipertahankan. Kombinasi ini berguna untuk menyaring outlier satu arah tanpa memengaruhi sisi lain.

clip Setara maximum(minimum(…)) #

Perilaku np.clip identik dengan menggabungkan dua ufunc pembanding: jepit dulu dengan np.minimum (batas atas), lalu dengan np.maximum (batas bawah). Kita verifikasi kesetaraannya pada array yang sama:

python
import numpy as np

x = np.array([-5, 0, 50, 300])
hasil_clip = np.clip(x, 0, 255)
hasil_manual = np.maximum(np.minimum(x, 255), 0)
print(hasil_clip)
print(hasil_manual)
print(np.array_equal(hasil_clip, hasil_manual))

Output yang Dihasilkan:

text
[  0   0  50 255]
[  0   0  50 255]
True

np.array_equal mengembalikan True, membuktikan kedua bentuk menghasilkan array yang sama persis. Susunan np.maximum di dalam dan np.minimum di luar inilah yang meniru np.clip; kesalahan yang sering terjadi adalah menukar posisi batas pada np.clip sendiri — np.clip(x, 255, 0) menjadikan seluruh elemen 0 karena batas atas 0 diterapkan paling akhir dan menimpa batas bawah.

Tabel berikut merangkum kapan masing-masing bentuk lebih cocok:

BentukCocok untuk
np.clip(a, min, max)Satu langkah terbaca, mendukung None per sisi
np.maximum(np.minimum(a, max), min)Kode tanpa fungsi khusus, atau saat nilai batas berupa array

Pada bentuk manual, a_min dan a_max juga boleh berupa array seukuran a, sehingga batas yang berbeda per elemen (misal rentang normal tiap sensor) tetap bisa dijepit dalam satu panggilan.