Konversi Tipe

astype, to_numeric dengan koersi error, dan perbaikan dtype yang salah baca.

Daftar isi

Kolom yang salah tipe membuat operasi numerik gagal dijalankan atau diam-diam menghasilkan angka yang keliru, sehingga perbaikan tipe data merupakan langkah pembersihan yang menjamin dtype sesuai isi kolomnya. Topik ini membahas astype untuk konversi langsung, pd.to_numeric dengan errors="coerce" untuk kolom teks yang memuat penanda hilang semacam --, kegagalan astype ke int pada kolom berisi NaN beserta tipe nullable Int64 sebagai alternatifnya, dan pd.to_datetime secara sekilas. Dataset log sensor versi kotor dipakai lagi, dengan kolom lembap_pct sengaja diubah menjadi teks yang meniru ekspor sistem pemantauan. Setelah topik ini dipraktikkan, kolom yang salah baca dari CSV dapat dikenali dan diperbaiki dengan cara yang tidak menghilangkan jejak kekotorannya.

Konversi langsung dengan astype#

Metode astype mengubah dtype seluruh kolom menuju tipe yang ditunjuk, dan konversi ini berlaku penuh atau gagal sama sekali karena setiap nilai harus dapat dikonversi. Contoh terkecilnya adalah deret teks angka yang dikonversi menuju int dan float.

python Konversi tipe dasar dengan astype
import pandas as pd

angka = pd.Series(["10", "20", "30"])
print(angka.dtype)
print(angka.astype(int).dtype)
print(angka.astype("float64").dtype)
text Keluaran
str
int64
float64

Keluaran tersebut menunjukkan tiga tahap yang sama pada satu deret, yaitu teks str menjadi int64 melalui astype(int) dan menjadi float64 melalui astype("float64"). Pola ini berlaku pada kolom apa pun selama isinya bersih, dan pada dataset log sensor kolom waktu bertipe str juga dapat dikonversi dengan cara yang sama apabila formatnya seragam. Masalah baru muncul ketika satu sel saja tidak dapat dikonversi, karena astype menaikkan error dan menghentikan seluruh proses. Perilaku menolak total itu sebenarnya berguna sebagai pemeriksaan, tetapi kolom hasil ekspor nyata jarang sekali bersih, sehingga alat yang lebih toleran dibutuhkan pada bagian berikutnya.

to_numeric dengan errors=“coerce”#

Fungsi pd.to_numeric mengonversi kolom menjadi numerik dengan opsi penanganan nilai yang tidak dapat dibaca, dan opsi errors="coerce" mengganti nilai bermasalah menjadi NaN alih-alih memunculkan error. Pada skrip di bawah ini kolom lembap_pct diubah menjadi versi teks yang memuat delapan penanda --, yaitu gabungan tiga NaN lama dan lima baris sampel yang dipilih dengan seed tetap. Kolom itu bertipe str dan isna() menghitung nol karena -- adalah teks biasa, bukan NaN. Setelah errors="coerce" dijalankan, dtype-nya menjadi float64 dan hitungan NaN menjadi 8, persis sebanyak penanda -- yang dikandungnya.

python konversi_tipe.py
import numpy as np
import pandas as pd

# Dataset kontrak versi kotor: log sensor tiga ruangan dengan NaN dan duplikat.
rng = np.random.default_rng(42)
n = 96
df = pd.DataFrame({
    "waktu": pd.date_range("2026-01-05 07:00", periods=n, freq="15min"),
    "ruang": rng.choice(["Lab A", "Lab B", "Ruang Arsip"], n, p=[0.4, 0.35, 0.25]),
    "suhu_c": np.round(rng.normal(24, 1.5, n), 1),
    "lembap_pct": np.round(rng.normal(60, 5, n), 1),
    "status_sensor": rng.choice(["normal", "kalibrasi", "rusak"], n, p=[0.85, 0.10, 0.05]),
})
df.loc[rng.random(n) < 0.05, "suhu_c"] = np.nan
df.loc[rng.random(n) < 0.05, "lembap_pct"] = np.nan
df = pd.concat([df, df.sample(3, random_state=42)], ignore_index=True)

# Versi teks kolom lembap_pct: NaN lama dan lima baris sampel ditandai "--".
df_teks = df.copy()
idx = df_teks.sample(frac=0.05, random_state=7).index
df_teks["lembap_pct"] = df_teks["lembap_pct"].astype("str").mask(df_teks["lembap_pct"].isna(), "--")
df_teks.loc[idx, "lembap_pct"] = "--"
print("dtype awal             :", df_teks["lembap_pct"].dtype)
print("NaN sebelum koersi     :", df_teks["lembap_pct"].isna().sum())
print("tanda --               :", (df_teks["lembap_pct"] == "--").sum())
siap = pd.to_numeric(df_teks["lembap_pct"], errors="coerce")
print("dtype setelah koersi   :", siap.dtype)
print("NaN setelah koersi     :", siap.isna().sum())
try:
    siap.astype(int)
except ValueError as e:
    print("ValueError:", e)
waktu_teks = df_teks["waktu"].astype(str)
print("dtype waktu sebagai teks :", waktu_teks.dtype)
print("dtype kembali ke tanggal :", pd.to_datetime(waktu_teks).dtype)
bash
# menjalankan skrip konversi tipe
python3 konversi_tipe.py
text Keluaran
dtype awal             : str
NaN sebelum koersi     : 0
tanda --               : 8
dtype setelah koersi   : float64
NaN setelah koersi     : 8
ValueError: Cannot convert non-finite values (NA or inf) to integer. Replace or remove non-finite values or cast to an integer type that supports these values (e.g. 'Int64')
dtype waktu sebagai teks : str
dtype kembali ke tanggal : datetime64[us]

Koersi semacam ini adalah koersi error (error coercion), yaitu menukar kebersihan tipe dengan kehilangan informasi posisi, karena tanda -- aslinya tidak lagi dapat dibedakan setelah menjadi NaN. Angka 8 sebelum dan sesudah koersi pada keluaran menunjukkan bahwa keduanya cocok satu-satu, dan pemeriksaan kecil semacam itu layak dijalankan setiap kali coerce dipakai. Apabila penandanya bukan -- melainkan simbol lain, parameter na_values pada read_csv yang dibahas pada topik Berkas CSV menanganinya sejak pembacaan, sedangkan to_numeric bekerja setelah data berada di memori.

astype ke int pada kolom berisi NaN dan tipe Int64#

Konversi kolom yang memuat NaN menuju int selalu gagal karena int standar tidak memiliki tempat untuk nilai hilang. Error pada keluaran skrip memunculkan pesan yang menyebutkan dua jalan keluarnya, yaitu mengganti atau membuang nilai non-finite terlebih dahulu, atau memakai tipe bilangan bulat yang mendukung nilai tersebut. Contoh terkecil berikut memperlihatkan kegagalan itu beserta solusinya.

python Konversi float berisi NaN ke Int64
import numpy as np
import pandas as pd

jumlah = pd.Series([3.0, np.nan, 5.0])
print(jumlah.dtype)
try:
    jumlah.astype(int)
except ValueError as e:
    print("ValueError:", e)
print(jumlah.astype("Int64"))
text Keluaran
float64
ValueError: Cannot convert non-finite values (NA or inf) to integer. Replace or remove non-finite values or cast to an integer type that supports these values (e.g. 'Int64')
0       3
1    <NA>
2       5
dtype: Int64

Tipe Int64 dengan huruf I kapital adalah tipe bilangan bulat nullable (nullable), yaitu tipe yang tetap bisa menampung nilai hilang di samping bilangan bulat, dan NaN pada deret aslinya tampil sebagai <NA>. Cukup diketahui di sini bahwa tipe semacam ini menyelesaikan kegagalan konversi di atas tanpa mengisi apa pun, dan topik dtype nullable pada jalur ini membahas keluarga tipe tersebut secara lengkap. Untuk kolom pengukuran seperti suhu dan kelembapan, float64 biasa sudah cukup karena tipe itu memang memiliki NaN, sehingga Int64 lebih relevan untuk kolom hitungan seperti jumlah pembacaan per jam.

to_datetime secara sekilas#

Fungsi pd.to_datetime mengubah teks tanggal menjadi tipe tanggal, dan pada keluaran skrip kolom waktu yang dijadikan teks lewat astype(str) kembali menjadi datetime64[us] setelah dilewatkan ke fungsi itu. Yang perlu diingat dari topik ini hanyalah mekanismenya, yaitu teks tanggal yang seragam formatnya dapat dikembalikan menjadi tipe tanggal kapan pun dibutuhkan, dan kegagalannya ditangani dengan errors="coerce" seperti pada to_numeric. Detail yang lebih dalam, seperti format tanggal yang tidak baku, resolusi unit waktu, dan indeks berwaktu, dibahas lengkap pada modul Deret Waktu karena di sana konversi ini menjadi fondasi, bukan pelengkap.

Kesalahan umum#

Kesalahan yang paling sering adalah memanggil astype pada kolom teks yang memuat penanda hilang, misalnya astype("float64") langsung pada kolom lembap_pct versi teks di atas, dan pemanggilan itu memunculkan error konversi karena teks -- tidak berarti apa pun secara numerik. Perbaikannya adalah pd.to_numeric(..., errors="coerce") yang mengubah penanda menjadi NaN, kemudian tipe numerik diperoleh tanpa menghentikan skrip. Kesalahan kedua adalah memercayai dtype hasil read_csv tanpa pemeriksaan, padahal satu kolom teks saja sudah menurunkan seluruh kolom numerik menjadi str seperti yang terlihat pada topik Berkas CSV. Kebiasaan yang menutup keduanya adalah mencetak dtypes setiap kali data dimuat, lalu memperbaiki tipe satu per satu dengan alat di topik ini sebelum analisis dimulai.

Ringkasan#

  • astype mengubah dtype seluruh kolom secara penuh atau gagal sama sekali, dan kegagalannya dipicu satu sel saja yang tidak terkonversi.
  • pd.to_numeric dengan errors="coerce" mengganti teks yang tidak terbaca menjadi NaN, sehingga hitungan NaN sebelum dan sesudah koersi wajib dibandingkan.
  • astype(int) selalu gagal pada kolom berisi NaN, dan tipe nullable Int64 menampung bilangan bulat beserta <NA> tanpa perlu pengisian.
  • pd.to_datetime mengembalikan teks tanggal menjadi datetime64[us], dan pembahasan mendalamnya berada pada modul Deret Waktu.

Referensi#