pyarrow-integration menyinggung backend arrow, dan pandas 3.0 menutup lingkaran itu di sisi bahasa: semua kolom teks baru kini memakai dtype str bawaan, bukan object warisan NumPy. DataFrame hasil read_csv() di era 3.0 sudah otomatis str, tetapi data lama yang berpindah dari pandas 2.x, dari berkas parquet lama, atau dari kolom yang sengaja dinyatakan object tetap berstatus object. Migrasi ke str adalah pekerjaan kecil dengan manfaat besar — pemeriksaan tipe lebih ketat dan integrasi arrow lebih mulus. Chapter ini membahas konversi lewat astype("str"), pembacaan ulang dengan dtype_backend="pyarrow", dan jebakan yang perlu diwaspadai.

Perbedaan yang Perlu Dipahami #

Dtype object adalah kotak serba bisa: string, angka, list, bahkan objek Python lain bisa berdampingan tanpa peringatan. Dtype str jauh lebih disiplin — hanya string dan nilai kosong yang boleh berdampingan. Perbedaan itu membuat kesalahan isi kolom terdeteksi lebih awal, dan missing value-nya konsisten NaN bukan variasi lain. Karena itu migrasi bukan sekadar ganti label dtype, melainkan pernyataan bahwa kolom tersebut memang kolom teks; kolom campuran yang seharusnya numerik tidak boleh dimigrasi, melainkan diperbaiki dtipenya lewat astype("int64") atau sejenisnya.

python
import io

import pandas as pd

# kolom object warisan pandas 2.x: bisa menampung apa saja
kota_lama = pd.Series(["Bandung", None, "Jakarta"], dtype="object", name="kota")
print(kota_lama.dtype)

# konversi ke dtype str pandas 3.0
kota_baru = kota_lama.astype("str")
print(kota_baru.dtype)
print("nilai:", kota_baru.tolist())

# read_csv bisa langsung memakai backend pyarrow sejak pembacaan
csv = io.StringIO("kota,unit\nBandung,12\nJakarta,30\n")
df_arrow = pd.read_csv(csv, dtype_backend="pyarrow")
print("dtype pyarrow:", df_arrow.dtypes.tolist())

# string kosong dan NaN tetap dua hal berbeda
campuran = pd.Series(["Bandung", "", None], dtype="str")
print("count non-null:", campuran.count())

Output yang Dihasilkan:

text
object
str
nilai: ['Bandung', nan, 'Jakarta']
dtype pyarrow: [string[pyarrow], int64[pyarrow]]
count non-null: 2

Mari kita telaah baris-baris kuncinya:

  1. Baris 6-7: Series dinyatakan object — bentuk warisan yang masih sah di pandas 3.0, terutama untuk data lama.
  2. Baris 10-12: astype("str") menghasilkan dtype str; nilai None tetap terbaca sebagai missing, bukan teks "None".
  3. Baris 16-17: read_csv(..., dtype_backend="pyarrow") membaca kolom langsung sebagai int64[pyarrow] dan string[pyarrow] tanpa konversi setelahnya.
  4. Baris 20-21: string kosong "" tetap terhitung nilai sah oleh count(), sedangkan None tidak — dua konsep yang berbeda sejak section data cleaning.

Dua Jalur Konversi #

Jalur pertama adalah per kolom: df["kolom"].astype("str") — tepat bila migrasi dilakukan bertahap dan hanya kolom tertentu yang sudah pasti teks. Jalur kedua adalah pembacaan ulang: pd.read_csv(..., dtype_backend="pyarrow") atau sekadar membiarkan pandas 3.0 menebak — string tiba sebagai str sejak baris pertama, jauh lebih hemat langkah bila data berasal dari berkas. Untuk tabel yang diawetkan ke format biner, baca sekali dengan backend arrow lalu simpan kembali sebagai Parquet; dtype str dan string[pyarrow] ikut terawetkan, sehingga pembaca berikutnya tidak mengerjakan migrasi lagi.

Jebakan yang Sering Muncul #

Tiga jebakan muncul berulang di lapangan. Pertama, astype("str") pada kolom campuran angka-dan-teks menjadikan semua isi teks — angka 12 menjadi "12" — dan seluruh perhitungan numerik ikut hilang; periksa isi kolom dengan df["kolom"].map(type).value_counts() sebelum memutuskan. Kedua, .values pada kolom str tidak lagi mengembalikan array NumPy biasa melainkan array string khusus; kode yang mengandalkan sifat ndarray perlu pindah ke .to_numpy(dtype=object) atau .astype(str) dengan kesadaran penuh. Ketiga, perbandingan silang dtype lama dan baru tetap bekerja untuk == dan merge, tetapi pemeriksaan dtype == object di kode utilitas harus diperbarui agar mengakui str — pola yang juga dibahas chapter debugging-dtype.

Dengan migrasi ini, dataset lama bisa merengkuh seluruh manfaat era 3.0 — dtype ketat, backend arrow, dan pemeriksaan dini. Chapter berikutnya melanjutkan ke sparse data, representasi hemat memori untuk kolom yang didominasi satu nilai berulang.

Dokumentasi resmi yang relevan: User Guide: Working with text data untuk perilaku dtype str, What’s new in pandas 3.0.0 yang mencatat pergantian bawaan, dan User Guide: PyArrow Functionality untuk dtype_backend="pyarrow".