Berkas CSV yang keluar dari sistem nyata hampir selalu kotor: pemisah bukan koma, baris judul terletak di atas header, tanggal tersimpan sebagai teks, dan nilai hilang ditandai simbol yang tidak baku. Topik ini membahas parameter read_csv yang paling menentukan hasil pembacaan, yaitu sep, header, names, na_values, parse_dates, dan dtype. Seluruh parameter dipraktikkan pada satu berkas log sensor yang sengaja dibuat kotor, sehingga efek setiap parameter dapat diamati langsung pada dtypes dan head. Setelah topik ini selesai, berkas kotor seperti ini dapat dibaca menjadi DataFrame dengan nama kolom dan tipe data yang benar.
Berkas latihan yang kotor#
Contoh sepanjang jalur ini adalah log sensor suhu dan kelembapan tiga ruangan, yaitu Lab A, Lab B, dan Ruang Arsip. Pada topik ini log tersebut tampil dalam versi kotor sebagaimana sering dijumpai pada ekspor aplikasi pemantauan ruangan. Dataset berantakan semacam ini menjadi bahan latihan banyak topik di jalur ini, dan versi bersihnya dapat dibangkitkan ulang dari generator deterministik seperti pada topik Basis Data dan Parquet. Jalankan skrip berikut untuk membuat berkasnya, kemudian amati isinya yang ditampilkan kembali oleh baris terakhir skrip.
from pathlib import Path
teks = """Ekspor otomatis;Sistem Monitoring Ruang;5 Januari 2026
waktu;ruang;suhu_c;lembap_pct;status_sensor
05/01/2026 07:00;Lab A;23.4;58.2;normal
05/01/2026 07:15;Lab B;24.1;61.3;normal
05/01/2026 07:30;Lab A;--;63.8;kalibrasi
05/01/2026 07:45;Ruang Arsip;22.8;57.5;normal
05/01/2026 08:00;Lab B;--;66.1;rusak
05/01/2026 08:15;Lab A;24.6;60.4;normal
05/01/2026 08:30;Lab B;23.9;62.7;normal
"""
Path("log_kotor.csv").write_text(teks, encoding="utf-8")
print(Path("log_kotor.csv").read_text(encoding="utf-8"), end="")# membuat berkas log_kotor.csv di direktori kerja
python3 buat_log_kotor.pyEkspor otomatis;Sistem Monitoring Ruang;5 Januari 2026
waktu;ruang;suhu_c;lembap_pct;status_sensor
05/01/2026 07:00;Lab A;23.4;58.2;normal
05/01/2026 07:15;Lab B;24.1;61.3;normal
05/01/2026 07:30;Lab A;--;63.8;kalibrasi
05/01/2026 07:45;Ruang Arsip;22.8;57.5;normal
05/01/2026 08:00;Lab B;--;66.1;rusak
05/01/2026 08:15;Lab A;24.6;60.4;normal
05/01/2026 08:30;Lab B;23.9;62.7;normalBerkas log_kotor.csv memuat lima kekotoran sekaligus. Baris pertama adalah judul laporan yang bukan nama kolom, dan baris kedua barulah header yang sesungguhnya. Pemisah antarkolomnya adalah titik koma, bukan koma. Kolom waktu berisi teks dengan urutan hari, bulan, lalu tahun, sedangkan dua baris menandai suhu hilang dengan tanda --. Skripnya menulis teks yang tetap, sehingga berkas yang dihasilkan identik pada setiap eksekusi dan seluruh keluaran topik ini dapat direproduksi.
Parameter sep#
Parameter sep menentukan karakter pemisah antarkolom, dan pembacaan yang benar dimulai dari menyamakan nilai ini dengan pemisah yang benar-benar dipakai berkas. Blok berikut membaca berkas latihan tanpa parameter apa pun untuk memperlihatkan akibatnya.
import pandas as pd
df = pd.read_csv("log_kotor.csv")
print(df.shape)
print(df.head(3))(8, 1)
Ekspor otomatis;Sistem Monitoring Ruang;5 Januari 2026
0 waktu;ruang;suhu_c;lembap_pct;status_sensor
1 05/01/2026 07:00;Lab A;23.4;58.2;normal
2 05/01/2026 07:15;Lab B;24.1;61.3;normalNilai default sep adalah koma, yaitu nilai yang dipakai ketika parameter tidak diisi. Berkas latihan dipisahkan titik koma, sehingga seluruh baris terbaca sebagai satu kolom tunggal dan judul laporan menjadi nama kolomnya. Hasil seperti ini jelas tidak terpakai, tetapi tidak ada pesan error yang membantu dan kekacauannya baru terlihat pada df.shape serta df.head().
import pandas as pd
df = pd.read_csv("log_kotor.csv", sep=";")
print(df.shape)
print(df.head(3))
print(df.dtypes)(8, 3)
Ekspor otomatis Sistem Monitoring Ruang 5 Januari 2026
waktu ruang suhu_c lembap_pct status_sensor
05/01/2026 07:00 Lab A 23.4 58.2 normal
05/01/2026 07:15 Lab B 24.1 61.3 normal
Ekspor otomatis str
Sistem Monitoring Ruang str
5 Januari 2026 str
dtype: objectBerkas kini terbelah menjadi kolom, tetapi hasilnya tetap salah. Baris judul dianggap header sehingga tabel hanya memiliki tiga kolom yang namanya berasal dari teks judul, sedangkan setiap baris data memuat lima nilai. pandas menelan dua nilai pertama setiap baris menjadi index bertingkat (MultiIndex) untuk menampung kelebihan itu, dan baris header asli ikut menjadi data. Kegagalan seperti ini berbahaya karena tidak memunculkan pesan error sama sekali.
Parameter header dan names#
Parameter header menunjuk nomor baris yang dipakai sebagai nama kolom, sedangkan names mengganti seluruh nama kolom dengan daftar yang diberikan secara eksplisit. Keduanya menyelesaikan masalah header yang tersisip pada berkas latihan.
import pandas as pd
df = pd.read_csv("log_kotor.csv", sep=";", header=1)
print(df.dtypes)
print(df.head(3))waktu str
ruang str
suhu_c str
lembap_pct float64
status_sensor str
dtype: object
waktu ruang suhu_c lembap_pct status_sensor
0 05/01/2026 07:00 Lab A 23.4 58.2 normal
1 05/01/2026 07:15 Lab B 24.1 61.3 normal
2 05/01/2026 07:30 Lab A -- 63.8 kalibrasiNilai header=1 berarti baris kedua berkas, yakni baris berindeks 1, dipakai sebagai nama kolom dan baris judul di atasnya dilewati. Tabel kini berbentuk benar dengan tujuh baris dan lima kolom. Perhatikan pula dtypes yang tampil: kolom teks ruang dan status_sensor bertipe str, kolom lembap_pct terbaca float64, sedangkan suhu_c ikut menjadi str karena tanda -- di dalamnya, dan waktu masih berupa teks.
import pandas as pd
df1 = pd.read_csv("log_kotor.csv", sep=";", header=1)
df2 = pd.read_csv(
"log_kotor.csv", sep=";", skiprows=2, header=None,
names=["waktu", "ruang", "suhu_c", "lembap_pct", "status_sensor"],
)
print(df1.columns.tolist())
print(df2.columns.tolist())
print(df1.equals(df2))['waktu', 'ruang', 'suhu_c', 'lembap_pct', 'status_sensor']
['waktu', 'ruang', 'suhu_c', 'lembap_pct', 'status_sensor']
TrueCara kedua tidak bergantung pada posisi header di dalam berkas. Parameter header=None menyatakan berkas tidak memiliki baris header, skiprows=2 melewati baris judul beserta baris header aslinya, lalu names memberi nama kolom baku. Hasil kedua cara identik, sebagaimana ditunjukkan nilai True dari equals. Pola names inilah yang dipakai ketika berkas sama sekali tidak memiliki header atau ketika nama kolom ingin dibakukan.
Parameter na_values#
Parameter na_values menambahkan teks tertentu ke daftar penanda nilai hilang sehingga kolom yang seharusnya numerik tidak salah baca menjadi teks. Tanda -- pada berkas latihan adalah penanda semacam itu, dan blok berikut memperlihatkan perbaikannya.
import pandas as pd
df = pd.read_csv("log_kotor.csv", sep=";", header=1, na_values="--")
print(df.dtypes)
print(df.head(3))waktu str
ruang str
suhu_c float64
lembap_pct float64
status_sensor str
dtype: object
waktu ruang suhu_c lembap_pct status_sensor
0 05/01/2026 07:00 Lab A 23.4 58.2 normal
1 05/01/2026 07:15 Lab B 24.1 61.3 normal
2 05/01/2026 07:30 Lab A NaN 63.8 kalibrasiSecara default read_csv sudah mengenal sejumlah penanda baku seperti teks kosong, NA, dan null, tetapi tanda -- bukan bagian darinya. Tanpa na_values, seluruh isi kolom suhu_c diperlakukan sebagai teks sehingga tipenya str. Setelah na_values="--", tanda tersebut dikonversi menjadi NaN dan kolomnya menjadi float64. Baris ketiga pada head memperlihatkan NaN yang mewakili suhu hilang, dan nilai hilang seperti ini siap diproses oleh metode penanganan data hilang pada modul Pembersihan.
Parameter parse_dates dan dtype#
Parameter parse_dates mengonversi kolom tanggal dari teks menjadi datetime saat pembacaan, sedangkan dtype memaksa tipe tertentu pada kolom yang dipilih. Keduanya menyelesaikan dua sisa masalah pada berkas latihan, yaitu kolom waktu yang masih teks dan tipe numerik yang belum sesuai kebutuhan.
import pandas as pd
df = pd.read_csv(
"log_kotor.csv", sep=";", header=1, na_values="--", parse_dates=["waktu"]
)
print(df["waktu"].head(3).tolist())[Timestamp('2026-05-01 07:00:00'), Timestamp('2026-05-01 07:15:00'), Timestamp('2026-05-01 07:30:00')]Konversi pertama ini menyimpan kejutan. pandas menebak format tanggal tanpa diberi tahu, dan tebakan itu mengikuti gaya Amerika Serikat yang menaruh bulan di depan. Log yang bertanggal 5 Januari 2026 pun terbaca sebagai 1 Mei 2026, dan tidak ada pesan error yang menandai kesalahan tersebut. Data yang sudah salah sejak pembacaan akan membawa kesalahan itu ke seluruh analisis di belakangnya.
import pandas as pd
df = pd.read_csv(
"log_kotor.csv", sep=";", header=1, na_values="--",
parse_dates=["waktu"], dayfirst=True,
)
print(df.dtypes)
print(df.head(3))waktu datetime64[us]
ruang str
suhu_c float64
lembap_pct float64
status_sensor str
dtype: object
waktu ruang suhu_c lembap_pct status_sensor
0 2026-01-05 07:00:00 Lab A 23.4 58.2 normal
1 2026-01-05 07:15:00 Lab B 24.1 61.3 normal
2 2026-01-05 07:30:00 Lab A NaN 63.8 kalibrasiDengan dayfirst=True, urutan hari-bulan-tahun dipakai dan ketiga waktu terbaca sebagai 5 Januari 2026. Tipe kolomnya tampil datetime64[us], yaitu datetime beresolusi mikrodetik yang menjadi bawaan pandas 3.x. Kolom waktu kini dapat diurutkan, disaring menurut rentang, dan diagregasi per periode seperti pada modul Deret Waktu.
import pandas as pd
df = pd.read_csv(
"log_kotor.csv", sep=";", header=1, na_values="--",
parse_dates=["waktu"], dayfirst=True,
dtype={"suhu_c": "float32", "lembap_pct": "float32"},
)
print(df.dtypes)
print(df.head(3))waktu datetime64[us]
ruang str
suhu_c float32
lembap_pct float32
status_sensor str
dtype: object
waktu ruang suhu_c lembap_pct status_sensor
0 2026-01-05 07:00:00 Lab A 23.4 58.200001 normal
1 2026-01-05 07:15:00 Lab B 24.1 61.299999 normal
2 2026-01-05 07:30:00 Lab A NaN 63.799999 kalibrasiParameter dtype menutup rangkaian ini dengan memaksa tipe tertentu sejak pembacaan, sehingga konversi sesudahnya tidak diperlukan. Nilai float32 memangkas memori kolom numerik menjadi separuhnya dibanding float64, dengan harga yang tampak pada keluaran: 58.2 tampil sebagai 58.200001. Angka itu adalah artefak presisi float32, bukan kekacauan data, dan perbedaan ini perlu dikenali ketika akurasi tinggi menjadi syarat analisis.
Kesalahan umum#
- Membaca berkas berpemisah titik koma tanpa parameter
sep. Seluruh baris jatuh ke satu kolom dan tabelnya mustahil dianalisis. Perbaikannya dengan menyamakansepdengan pemisah berkas, lalu periksadf.shapeuntuk memastikan jumlah kolom masuk akal. - Kolom tanggal tetap bertipe teks karena
parse_datestidak diisi, sehingga penyaringan dan agregasi berbasis waktu gagal. Isiparse_datespada saat membaca, dan tambahkandayfirst=Truebila urutan harinya lebih dahulu. - Kolom numerik menjadi teks karena penanda nilai hilang tidak dikenal, misalnya tanda
--. Cantumkan semua penanda padana_values, atau konversi sesudah pembacaan denganto_numericsebagaimana dibahas pada topik Konversi Tipe.
Ringkasan#
sepharus sama dengan pemisah berkas, karena pemisah yang keliru tidak selalu memicu error melainkan menghasilkan tabel yang salah secara diam-diam.headermenunjuk baris yang dipakai sebagai nama kolom, sedangkanheader=Nonedikombinasikan dengannamesmemberi nama kolom baku untuk berkas tanpa header.na_valuesmengubah penanda seperti tanda--menjadiNaNsehingga kolom numerik terbacafloat64.parse_datesdengandayfirst=Truemengubah teks tanggal menjadidatetime64[us], sedangkandtypememaksa tipe kolom tertentu sejak pembacaan.
Referensi#
- pandas.read_csv — pandas documentation
— Daftar lengkap parameter
read_csv, termasuksep,header,names,na_values,parse_dates,dayfirst, dandtype. - IO tools (text, CSV, HDF5, …) — pandas documentation — Panduan resmi baca tulis data yang menjelaskan perilaku parser CSV dan penanganan nilai hilang.