Data teks jarang hadir dalam keadaan siap pakai. Kita sering perlu menjawab pertanyaan seperti: baris mana yang merupakan kode pesanan, berapa kali pola tertentu muncul, atau teks apa yang harus diganti sebelum data layak dianalisis. Chapter ini membahas lima fungsi pencarian dan penggantian pada namespace np.strings: find, count, replace, startswith, dan endswith.

Kelima fungsi bekerja sebagai ufunc vectorized: satu pemanggilan memproses seluruh elemen array sekaligus tanpa loop Python. Gambaran cakupannya:

  • find: posisi substring pertama pada setiap elemen (array int, -1 bila tidak ditemukan).
  • count: jumlah kemunculan substring pada setiap elemen (array int).
  • replace: string baru hasil penggantian (array string).
  • startswith dan endswith: uji awalan dan akhiran (array bool, bahan mask boolean).

Fondasi namespace ini sudah dibahas pada Chapter np.strings Dasar, sedangkan sifat dtype string lebar-tetap <U ada pada Chapter Tipe Data String dan Object.

Mencari Posisi dan Menghitung Kemunculan #

np.strings.find(array, sub) mengembalikan array integer berisi indeks kemunculan pertama sub pada setiap elemen. Bila substring tidak ditemukan, hasilnya -1, bukan error. Sementara itu, np.strings.count(array, sub) menghitung banyaknya kemunculan sub yang tidak tumpang-tindih (non-overlapping) pada setiap elemen. Mari kita amati keduanya pada array kode pesanan:

python
import numpy as np

kode = np.array(["ID-101", "REG-202", "ID-105", "REG-208"])
posisi = np.strings.find(kode, "ID-")
print(posisi)
print(np.strings.find(kode, "X"))
print(np.strings.count(kode, "0"))
print(np.strings.count(kode, "20"))

Output yang Dihasilkan:

text
[ 0 -1  0 -1]
[-1 -1 -1 -1]
[1 1 1 1]
[0 1 0 1]

Mari kita bedah baris demi baris:

  1. Baris 3 (np.array([...])): interpreter membuat array string dengan dtype <U7, mengikuti elemen terpanjang "REG-202".
  2. Baris 5 (print(posisi)): find mengembalikan array int64. Elemen pertama dan ketiga diawali "ID-", sehingga posisinya 0; elemen lain tidak memuatnya, sehingga bernilai -1.
  3. Baris 6 (np.strings.find(kode, "X")): tidak ada elemen yang memuat "X", maka seluruh hasilnya -1.
  4. Baris 7-8 (np.strings.count(...)): setiap elemen memuat satu digit "0", sedangkan pola "20" hanya ada pada REG-202 dan REG-208.

Mengganti Teks dengan replace #

np.strings.replace(array, lama, baru) mengembalikan array string baru berisi hasil penggantian. Argumen opsional count membatasi jumlah penggantian per elemen, sehingga penggantian berhenti setelah batas tercapai:

python
import numpy as np

kode = np.array(["ID-101", "REG-202", "ID-105", "REG-208"])
print(np.strings.replace(kode, "ID-", "NP-"))
print(np.strings.replace(kode, "1", "X", count=1))

Output yang Dihasilkan:

text
['NP-101' 'REG-202' 'NP-105' 'REG-208']
['ID-X01' 'REG-202' 'ID-X05' 'REG-208']

Baris pertama mengganti seluruh awalan "ID-" menjadi "NP-", sedangkan elemen REG-202 dan REG-208 tidak tersentuh karena tidak memuat pola tersebut. Baris kedua membatasi penggantian satu kali per elemen: digit "1" pertama pada ID-101 menjadi X, tetapi digit "1" berikutnya tetap. Array asli tidak pernah berubah; replace menghasilkan array baru.

Menguji Awalan dan Akhiran untuk Filter Mask #

np.strings.startswith dan np.strings.endswith mengembalikan array bool. Kombinasi keduanya dengan boolean mask adalah pola kerja yang paling sering dipakai: menguji setiap baris, lalu memilih baris yang lolos uji.

python
import numpy as np

kode = np.array(["ID-101", "REG-202", "ID-105", "REG-208"])
mask_id = np.strings.startswith(kode, "ID-")
print(mask_id)
print(kode[mask_id])
mask_akhir = np.strings.endswith(kode, "208")
print(kode[mask_akhir])

Output yang Dihasilkan:

text
[ True False  True False]
['ID-101' 'ID-105']
['REG-208']
  1. Baris 4 (mask_id = ...): startswith menguji setiap elemen terhadap awalan "ID-" dan menghasilkan array bool.
  2. Baris 6 (kode[mask_id]): mask bool dipakai sebagai indeks, sehingga hanya baris yang bernilai True yang terpilih. Pola ini dibahas mendalam pada Chapter Boolean Indexing.
  3. Baris 7-8: endswith bekerja sama, tetapi menguji bagian akhir string.

split dan join Belum Ada di np.strings #

Namespace np.strings di NumPy 2.1.3 masih tumbuh secara bertahap. Dua fungsi yang populer, split dan join, belum tersedia di sana dan masih tinggal di namespace legasi np.char. Bila kita memanggilnya, NumPy memunculkan AttributeError:

python
import numpy as np

try:
    print(np.strings.split(np.array(["kopi gula"])))
except AttributeError as e:
    print("AttributeError:", e)
print(np.char.split(np.array(["kopi gula"])))

Output yang Dihasilkan:

text
AttributeError: module 'numpy.strings' has no attribute 'split'
[list(['kopi', 'gula'])]

Dengan lima fungsi di atas, kita sudah mampu mencari, menghitung, mengganti, dan memfilter teks secara vectorized. Semua teknik ini disatukan dalam studi kasus nyata pada Chapter Pembersihan Data Teks.