read_csv Secara Mendalam

Parameter sep, header, names, dtype, parse_dates, dan na_values pada read_csv beserta efeknya.

Daftar isi

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.

python buat_log_kotor.py
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="")
bash
# membuat berkas log_kotor.csv di direktori kerja
python3 buat_log_kotor.py
text Keluaran
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

Berkas 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.

python Contoh: pembacaan tanpa parameter sep
import pandas as pd

df = pd.read_csv("log_kotor.csv")
print(df.shape)
print(df.head(3))
text Keluaran
(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;normal

Nilai 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().

python Contoh: sep titik koma tanpa pengaturan header
import pandas as pd

df = pd.read_csv("log_kotor.csv", sep=";")
print(df.shape)
print(df.head(3))
print(df.dtypes)
text Keluaran
(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: object

Berkas 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.

python Contoh: header pada baris kedua
import pandas as pd

df = pd.read_csv("log_kotor.csv", sep=";", header=1)
print(df.dtypes)
print(df.head(3))
text Keluaran
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     kalibrasi

Nilai 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.

python Contoh: names sebagai pengganti header
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))
text Keluaran
['waktu', 'ruang', 'suhu_c', 'lembap_pct', 'status_sensor']
['waktu', 'ruang', 'suhu_c', 'lembap_pct', 'status_sensor']
True

Cara 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.

python Contoh: na_values untuk tanda data hilang
import pandas as pd

df = pd.read_csv("log_kotor.csv", sep=";", header=1, na_values="--")
print(df.dtypes)
print(df.head(3))
text Keluaran
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     kalibrasi

Secara 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.

python Contoh: parse_dates tanpa dayfirst
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())
text Keluaran
[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.

python Contoh: parse_dates dengan dayfirst
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))
text Keluaran
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     kalibrasi

Dengan 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.

python Contoh: dtype float32 untuk kolom numerik
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))
text Keluaran
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     kalibrasi

Parameter 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 menyamakan sep dengan pemisah berkas, lalu periksa df.shape untuk memastikan jumlah kolom masuk akal.
  • Kolom tanggal tetap bertipe teks karena parse_dates tidak diisi, sehingga penyaringan dan agregasi berbasis waktu gagal. Isi parse_dates pada saat membaca, dan tambahkan dayfirst=True bila urutan harinya lebih dahulu.
  • Kolom numerik menjadi teks karena penanda nilai hilang tidak dikenal, misalnya tanda --. Cantumkan semua penanda pada na_values, atau konversi sesudah pembacaan dengan to_numeric sebagaimana dibahas pada topik Konversi Tipe.

Ringkasan#

  • sep harus sama dengan pemisah berkas, karena pemisah yang keliru tidak selalu memicu error melainkan menghasilkan tabel yang salah secara diam-diam.
  • header menunjuk baris yang dipakai sebagai nama kolom, sedangkan header=None dikombinasikan dengan names memberi nama kolom baku untuk berkas tanpa header.
  • na_values mengubah penanda seperti tanda -- menjadi NaN sehingga kolom numerik terbaca float64.
  • parse_dates dengan dayfirst=True mengubah teks tanggal menjadi datetime64[us], sedangkan dtype memaksa tipe kolom tertentu sejak pembacaan.

Referensi#