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.

csv
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,Dewi

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

python
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:

text
      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-5212

Mari kita telaah baris-baris pentingnya:

  1. 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.
  2. Baris 6 (df.dtypes): kolom harga menjadi int64 karena seluruh isinya angka, tetapi kolom jumlah menjadi object — tipe teks — karena memuat campuran angka dan tanda -. Menebak gagal, dan pandas memilih tipe paling aman.
  3. Baris 8 (df["jumlah"].sum()): inilah akibat yang tidak diinginkan. Penjumlahan tidak mengeluarkan galat; angka-angka dan tanda minus justru direkatkan menjadi teks 32142-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 .

python
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:

text
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.0

Mari kita telaah baris-baris pentingnya:

  1. Baris 3 (na_values=["-"]): setiap - pada berkas diubah menjadi NaN saat dibaca. Penanda lain yang umum — kosong, n/a, ? — dapat didaftarkan sekaligus dalam list yang sama.
  2. Baris 7 (df.isna().sum()): jumlah nilai hilang per kolom terhitung seketika: satu pada jumlah, satu pada pelanggan. Ringkasan seperti ini menentukan langkah pembersihan berikutnya.
  3. Baris 9 (df["jumlah"].sum()): kini penjumlahan berjalan benar — 22.0. Tipe kolom berubah menjadi float64 karena hanya tipe desimal yang sanggup menyimpan NaN; 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.

python
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:

text
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: object

Mari kita telaah baris-baris pentingnya:

  1. Baris 3-6 (try/except): memaksa int64 pada kolom yang memuat NaN ditolak pandas dengan ValueError. Pesan galat ditangkap lalu dicetak agar terbaca, bukan dibiarkan sebagai traceback.
  2. Baris 8-13 (pd.read_csv(...)): pembacaan berhasil dengan tiga penyesuaian sekaligus — - menjadi NaN, hanya tiga kolom dimuat, dan jumlah ditetapkan float64 secara eksplisit.
  3. 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.

python
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:

text
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: object

Mari kita telaah baris-baris pentingnya:

  1. Baris 14-16 (TemporaryDirectory): berkas mini harga_komoditas.csv ditulis ke folder sementara lalu dibaca — folder dan berkasnya terhapus sendiri saat blok with selesai.
  2. Baris 18-19 (pd.read_csv(berkas)): tanpa sep, seluruh baris dianggap satu nilai; buktinya hanya ada satu kolom bernama tanggal;komoditas;harga_rata. Gejala satu kolom panjang adalah tanda paling khas pemisah yang keliru.
  3. Baris 21 (sep=";", decimal=","): dengan kedua parameter, kolom terpisah benar dan 14500,50 terbaca sebagai 14500.50 bertipe float64 — 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 menjadi object dan menghasilkan penjumlahan yang salah tanpa galat; na_values mengubahnya menjadi NaN dan mengembalikan tipe numerik.
  • usecols memuat hanya kolom yang diperlukan, dtype menetapkan tipe secara eksplisit; kolom bernilai NaN hanya mungkin float64, bukan int64.
  • Ekspor pengaturan bahasa Indonesia kerap memakai titik koma dan desimal koma; sep=";" dan decimal="," menanganinya.
  • Periksa dtypes dan 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 .