Entri manual yang tervalidasi biasanya berakhir sebagai berkas: aplikasi kasir mengekspor penjualan harian, pedoman entri menghasilkan rekap mingguan, dan dataset terbuka diunduh dalam format yang sama. Format itu bernama CSV (comma-separated values) — teks polos yang hampir semua alat data sanggup membaca. Pada chapter ini kita memuat berkas CSV ke pandas dengan pd.read_csv(), mulai dari pembacaan default, penanganan nilai yang gagal terbaca, pemilihan kolom, penentuan tipe, hingga jebakan pemisah titik koma dan desimal koma yang sering menyertai ekspor dari aplikasi lembar kerja.
Bentuk Berkas CSV #
CSV menyimpan tabel sebagai teks: setiap baris tabel menjadi satu baris teks, nilai antar kolom dipisah tanda koma, dan baris pertama menyimpan nama kolom (header). Keunggulan format ini sederhana namun menentukan: berkasnya kecil, dapat dibuka di editor teks apa pun, dan dipahami hampir semua bahasa pemrograman. Berkas latihan chapter ini, penjualan.csv, adalah ekspor lima hari penjualan Toko Kopi Kita — perhatikan tanda - pada dua baris: begitulah aplikasi kasir menandai nilai yang tidak tercatat.
tanggal,produk,jumlah,harga,pelanggan
2026-01-15,kopi susu,3,24000,Budi
2026-01-15,teh tawar,2,20000,Siti
2026-01-16,kopi susu,1,24000,Dewi
2026-01-16,matcha latte,4,28000,Rani
2026-01-17,americano,2,22000,Budi
2026-01-17,teh tawar,-,20000,Agus
2026-01-18,kopi susu,5,24000,Siti
2026-01-18,matcha latte,2,28000,-
2026-01-19,americano,1,22000,Budi
2026-01-19,kopi susu,2,24000,DewiMembaca Default dengan read_csv #
Kita mulai tanpa parameter apa pun — begitulah read_csv() dipakai sehari-hari. Setelah membaca, kebiasaan pertama yang perlu dibiasakan adalah memeriksa tipe setiap kolom lewat dtypes, karena tampilan tabel saja dapat menyesatkan. Rujukan lengkap seluruh parameter tersedia di dokumentasi pandas.read_csv
.
import pandas as pd
df = pd.read_csv("penjualan.csv")
print(df)
print()
print(df.dtypes)
print()
print('Hasil df["jumlah"].sum() tanpa na_values:', df["jumlah"].sum())Output yang Dihasilkan:
tanggal produk jumlah harga pelanggan
0 2026-01-15 kopi susu 3 24000 Budi
1 2026-01-15 teh tawar 2 20000 Siti
2 2026-01-16 kopi susu 1 24000 Dewi
3 2026-01-16 matcha latte 4 28000 Rani
4 2026-01-17 americano 2 22000 Budi
5 2026-01-17 teh tawar - 20000 Agus
6 2026-01-18 kopi susu 5 24000 Siti
7 2026-01-18 matcha latte 2 28000 -
8 2026-01-19 americano 1 22000 Budi
9 2026-01-19 kopi susu 2 24000 Dewi
tanggal object
produk object
jumlah object
harga int64
pelanggan object
dtype: object
Hasil df["jumlah"].sum() tanpa na_values: 32142-5212Mari kita telaah baris-baris pentingnya:
- Baris 3 (
pd.read_csv("penjualan.csv")): pandas membuka berkas, menjadikan baris pertama sebagai nama kolom, memakai koma sebagai pemisah, lalu menebak tipe setiap kolom dari isinya. - Baris 6 (
df.dtypes): kolomhargamenjadiint64karena seluruh isinya angka, tetapi kolomjumlahmenjadiobject— tipe teks — karena memuat campuran angka dan tanda-. Menebak gagal, dan pandas memilih tipe paling aman. - Baris 8 (
df["jumlah"].sum()): inilah akibat yang tidak diinginkan. Penjumlahan tidak mengeluarkan galat; angka-angka dan tanda minus justru direkatkan menjadi teks32142-5212— angka yang sama sekali tidak bermakna.
Menandai Nilai Hilang dengan na_values #
Aplikasi kasir menandai kekosongan dengan -, sementara pandas hanya mengenali penanda bawaan seperti sel kosong. Parameter na_values menjembatani keduanya: semua nilai yang tercantum di sana diubah menjadi NaN, penanda nilai hilang milik pandas. Pembahasan lengkap tentang penanganan NaN tersedia pada dokumentasi missing data pandas
.
import pandas as pd
df = pd.read_csv("penjualan.csv", na_values=["-"])
print(df.dtypes)
print()
print("Jumlah nilai hilang per kolom:")
print(df.isna().sum())
print()
print("Total cangkir terjual:", df["jumlah"].sum())Output yang Dihasilkan:
tanggal object
produk object
jumlah float64
harga int64
pelanggan object
dtype: object
Jumlah nilai hilang per kolom:
tanggal 0
produk 0
jumlah 1
harga 0
pelanggan 1
dtype: int64
Total cangkir terjual: 22.0Mari kita telaah baris-baris pentingnya:
- Baris 3 (
na_values=["-"]): setiap-pada berkas diubah menjadiNaNsaat dibaca. Penanda lain yang umum —kosong,n/a,?— dapat didaftarkan sekaligus dalam list yang sama. - Baris 7 (
df.isna().sum()): jumlah nilai hilang per kolom terhitung seketika: satu padajumlah, satu padapelanggan. Ringkasan seperti ini menentukan langkah pembersihan berikutnya. - Baris 9 (
df["jumlah"].sum()): kini penjumlahan berjalan benar —22.0. Tipe kolom berubah menjadifloat64karena hanya tipe desimal yang sanggup menyimpanNaN;sum()juga otomatis melewati nilai hilang.
Memilih Kolom dan Menetapkan Tipe #
Dua parameter berikutnya menghemat kerja di analisis lanjutan. usecols memuat hanya kolom yang diperlukan — penting ketika berkas berpuluh kolom padahal analisis cuma memakai tiga; dtype menetapkan tipe secara eksplisit alih-alih menyerah pada tebakan. Satu batasan perlu dibuktikan langsung: kolom yang memuat NaN tidak dapat bertipe bilangan bulat.
import pandas as pd
try:
pd.read_csv("penjualan.csv", na_values=["-"], dtype={"jumlah": "int64"})
except ValueError as galat:
print("Galat bila jumlah dipaksa int64:", galat)
print()
df_ringkas = pd.read_csv(
"penjualan.csv",
na_values=["-"],
usecols=["tanggal", "produk", "jumlah"],
dtype={"jumlah": "float64"},
)
print(df_ringkas)
print()
print(df_ringkas.dtypes)Output yang Dihasilkan:
Galat bila jumlah dipaksa int64: Integer column has NA values in column 2
tanggal produk jumlah
0 2026-01-15 kopi susu 3.0
1 2026-01-15 teh tawar 2.0
2 2026-01-16 kopi susu 1.0
3 2026-01-16 matcha latte 4.0
4 2026-01-17 americano 2.0
5 2026-01-17 teh tawar NaN
6 2026-01-18 kopi susu 5.0
7 2026-01-18 matcha latte 2.0
8 2026-01-19 americano 1.0
9 2026-01-19 kopi susu 2.0
tanggal object
produk object
jumlah float64
dtype: objectMari kita telaah baris-baris pentingnya:
- Baris 3-6 (
try/except): memaksaint64pada kolom yang memuatNaNditolak pandas denganValueError. Pesan galat ditangkap lalu dicetak agar terbaca, bukan dibiarkan sebagai traceback. - Baris 8-13 (
pd.read_csv(...)): pembacaan berhasil dengan tiga penyesuaian sekaligus —-menjadiNaN, hanya tiga kolom dimuat, danjumlahditetapkanfloat64secara eksplisit. - Hasil
usecols: DataFrame hanya memuat tiga kolom. Selain mempercepat pembacaan, pemilihan kolom membuat cetakan tabel tetap terbaca pada layar sempit.
Pemisah Titik Koma dan Desimal Koma #
Ekspor dari aplikasi lembar kerja pada pengaturan bahasa Indonesia — dan sebagian besar Eropa — kerap memakai dua kebiasaan yang berbeda dari standar CSV: nilai dipisah titik koma, dan angka desimal ditulis dengan koma. Keduanya ditangani parameter sep dan decimal. Karena berkas latihan tambahan hanya dipakai sekali, ia dibuat di folder sementara TemporaryDirectory() yang terhapus otomatis, sehingga bundle chapter tetap bersih.
import tempfile
from pathlib import Path
import pandas as pd
isi_csv = (
"tanggal;komoditas;harga_rata\n"
"2026-01-15;beras;14500,50\n"
"2026-01-15;cabai merah;48000,00\n"
"2026-01-16;beras;14520,75\n"
"2026-01-16;cabai merah;51000,00\n"
)
with tempfile.TemporaryDirectory() as folder:
berkas = Path(folder) / "harga_komoditas.csv"
berkas.write_text(isi_csv, encoding="utf-8")
df_koma = pd.read_csv(berkas)
print("Dibaca dengan pemisah default:", list(df_koma.columns))
print()
df_benar = pd.read_csv(berkas, sep=";", decimal=",")
print(df_benar)
print()
print(df_benar.dtypes)Output yang Dihasilkan:
Dibaca dengan pemisah default: ['tanggal;komoditas;harga_rata']
tanggal komoditas harga_rata
0 2026-01-15 beras 14500.50
1 2026-01-15 cabai merah 48000.00
2 2026-01-16 beras 14520.75
3 2026-01-16 cabai merah 51000.00
tanggal object
komoditas object
harga_rata float64
dtype: objectMari kita telaah baris-baris pentingnya:
- Baris 14-16 (
TemporaryDirectory): berkas miniharga_komoditas.csvditulis ke folder sementara lalu dibaca — folder dan berkasnya terhapus sendiri saat blokwithselesai. - Baris 18-19 (
pd.read_csv(berkas)): tanpasep, seluruh baris dianggap satu nilai; buktinya hanya ada satu kolom bernamatanggal;komoditas;harga_rata. Gejala satu kolom panjang adalah tanda paling khas pemisah yang keliru. - Baris 21 (
sep=";", decimal=","): dengan kedua parameter, kolom terpisah benar dan14500,50terbaca sebagai14500.50bertipefloat64— siap dipakai berhitung.
Dua Jebakan yang Menyertai CSV #
Pemisah keliru dan desimal koma di atas adalah dua jebakan yang paling sering; dua lagi pantas diingat sejak awal. Pertama, baris header yang tidak ada membuat baris data pertama dijadikan nama kolom — parameter header mengaturnya. Kedua, encoding: berkas teks disimpan dengan tabel karakter tertentu, dan read_csv menganggapnya UTF-8 secara bawaan. Berkas dari sistem lawas Eropa Barat kadang memakai Latin-1; gejalanya pesan UnicodeDecodeError saat membaca, dan solusinya adalah meneruskan encoding="latin-1" — dengan catatan berkas UTF-8 modern, termasuk yang memuat emoji, justru akan gagal dibaca dengan Latin-1.
Rangkuman #
- CSV menyimpan tabel sebagai teks dengan koma pemisah;
pd.read_csv()memuatnya menjadi DataFrame dan menebak tipe setiap kolom. - Simbol penanda kosong seperti
-membuat kolom menjadiobjectdan menghasilkan penjumlahan yang salah tanpa galat;na_valuesmengubahnya menjadiNaNdan mengembalikan tipe numerik. usecolsmemuat hanya kolom yang diperlukan,dtypemenetapkan tipe secara eksplisit; kolom bernilaiNaNhanya mungkinfloat64, bukanint64.- Ekspor pengaturan bahasa Indonesia kerap memakai titik koma dan desimal koma;
sep=";"dandecimal=","menanganinya. - Periksa
dtypesdan bentuk kolom setiap selesai membaca — kebanyakan masalah CSV terlihat dari dua pemeriksaan ringan itu.
CSV menuntaskan sebagian besar kebutuhan pertukaran data, tetapi dunia kerja menyimpan banyak laporan dalam format Excel: satu berkas berisi beberapa sheet, baris judul di atas tabel, hingga tata letak yang dirancang untuk dibaca manusia. Cara membacanya di pandas menjadi pokok chapter berikutnya, Membaca File Excel .