CSV lebih sederhana dari kelihatannya (dan lebih rumit dari dugaanmu)
File CSV hanyalah teks: baris dipisahkan oleh newline, field dipisahkan oleh koma. Itu idenya. Kenyataannya, kamu akan bertemu string bertanda kutip yang berisi koma, field yang berisi newline, konvensi regional yang berbeda (koma vs titik koma), dan file yang disimpan dari Excel dengan BOM. Kasus khususnya cukup banyak sehingga menulis line.split(",") sendiri hampir selalu keputusan yang salah.
Modul bawaan csv di Python menangani semuanya. Untuk file kecil sampai menengah, kamu jarang butuh yang lain.
Membaca CSV dengan csv.reader
csv.reader menghasilkan setiap baris sebagai list berisi string:
import csv
with open("people.csv", newline="") as f:
reader = csv.reader(f)
for row in reader:
print(row)
Beberapa detail yang tidak langsung terlihat:
- Selalu berikan
newline=""keopen. Modul csv menangani akhir baris sendiri; tanpa ini, kamu akan mendapat baris kosong ekstra di Windows. - Setiap nilai adalah string.
"42"tetap string sampai kamu memanggilint(...)padanya. CSV tidak punya tipe data. - Baris header hanyalah baris biasa. Kalau filemu punya header, lewati baris pertama secara manual atau beralih ke
DictReader.
Melewati baris header
import csv
with open("people.csv", newline="") as f:
reader = csv.reader(f)
headers = next(reader) # pulls the first row out
for row in reader:
print(row)
next(reader) memajukan iterator satu langkah dan mengembalikan baris itu.
Membaca sebagai dict dengan DictReader
csv.DictReader menganggap baris pertama sebagai header dan memberimu setiap baris berikutnya sebagai dict:
import csv
with open("people.csv", newline="") as f:
reader = csv.DictReader(f)
for row in reader:
print(row["name"], row["email"])
Hampir selalu inilah yang kamu inginkan. Nama kolom menjelaskan dirinya sendiri, dan mengubah urutan kolom di file sumber tidak merusak kodemu.
Kalau file tidak punya header, berikan header secara eksplisit dengan fieldnames=["name", "email", ...].
Menulis CSV dengan csv.writer
csv.writer mengubah baris (list) menjadi baris CSV:
import csv
rows = [
["name", "age", "city"],
["Rosa", 30, "Lisbon"],
["Ada", 36, "London"],
]
with open("out.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerows(rows)
writerow(row) menulis satu baris; writerows(rows) menulis seluruh iterable sekaligus. Keduanya otomatis memberi tanda kutip pada field yang berisi koma, tanda kutip, atau newline, jadi kamu tidak perlu memikirkannya.
Menulis dict dengan DictWriter
Kalau datamu sudah berbentuk dict, DictWriter melewati langkah "ubah ke list":
import csv
people = [
{"name": "Rosa", "age": 30, "city": "Lisbon"},
{"name": "Ada", "age": 36, "city": "London"},
]
with open("out.csv", "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=["name", "age", "city"])
writer.writeheader()
writer.writerows(people)
Argumen fieldnames mengatur header sekaligus urutan kolom. Key di dict-mu yang tidak ada di fieldnames dibuang diam-diam (atau kamu bisa memunculkan error dengan extrasaction="raise").
Delimiter dan quoting yang berbeda
Tidak semua "CSV" memakai koma. Lokal Eropa sering memakai ;, file yang dipisahkan tab memakai \t, dan beberapa sistem memakai |. Berikan argumen delimiter=:
import csv
with open("data.tsv", newline="") as f:
reader = csv.reader(f, delimiter="\t")
for row in reader:
print(row)
Untuk file dengan aturan quoting yang tidak biasa, csv.register_dialect(...) memungkinkan kamu mengatur sekali lalu memakainya berulang kali. Untuk kebanyakan file, nilai default ditambah delimiter= sudah cukup.
Encoding
File CSV adalah teks, jadi punya encoding. UTF-8 adalah default modern; file dari Excel di Windows kadang memakai cp1252 atau menyertakan BOM UTF-8. Tulis secara eksplisit:
with open("data.csv", newline="", encoding="utf-8") as f:
reader = csv.DictReader(f)
...
Kalau kamu melihat UnicodeDecodeError, berarti encoding file itu bukan yang kamu tebak. Coba tersangka yang umum: utf-8-sig (menangani BOM dari Excel), cp1252, atau latin-1.
Mengubah baris CSV menjadi tipe yang berguna
Karena setiap nilai datang sebagai string, mengurainya (parsing) adalah tugasmu:
(StringIO membuat contoh ini bisa dijalankan tanpa file sungguhan; di kode nyata kamu akan memakai open(path).)
Untuk CSV dengan tipe yang rumit (tanggal, angka yang bisa kosong, true/false dengan sepuluh ejaan berbeda), pertimbangkan pandas, yang sudah punya konvensi bawaan untuk sebagian besar kasus itu.
Kapan beralih ke pandas
pandas.read_csv(path) mengembalikan sebuah DataFrame, struktur yang tepat begitu kamu ingin:
- Memfilter baris:
df[df["active"] == True] - Mengagregasi:
df.groupby("city")["age"].mean() - Menggabungkan dengan tabel lain
- Menulis kembali dengan format sederhana
import pandas as pd
df = pd.read_csv("people.csv")
adults = df[df["age"] >= 18]
adults.to_csv("adults.csv", index=False)
Pandas berlebihan untuk pembacaan kecil yang lurus dari awal sampai akhir, dan merupakan dependensi yang berat (install dengan pip di virtual environment). Tapi untuk apa pun yang berbentuk data, pandas adalah alat yang paling sering dipakai analis Python.
Streaming file yang sangat besar
csv.reader sudah bersifat lazy: ia membaca satu baris setiap kali. Pertahankan dengan melakukan perulangan (bukan memanggil list(reader) di awal), dan pemakaian memorimu tetap datar berapa pun ukuran filenya:
import csv
with open("huge.csv", newline="") as f:
reader = csv.DictReader(f)
error_count = 0
for row in reader:
if row["status"] == "error":
error_count += 1
print(f"Found {error_count} errors.")
Kode itu menangani file 10 GB sama lancarnya dengan file 10 KB, selama kamu tidak menumpuk baris-barisnya ke dalam list.
Beberapa kebiasaan baik
- Selalu berikan
newline=""keopensaat membaca atau menulis CSV. - Pakai
DictReader/DictWritersetiap kali file punya header, karena lebih mudah dibaca daripada indeks angka. - Tulis encoding secara eksplisit, terutama untuk file dari Excel atau sumber berbahasa selain Inggris.
- Ubah tipe data langsung di tahap membaca agar kode selanjutnya tidak perlu melakukannya.
- Beralih ke pandas begitu kamu ingin menganalisis data, bukan sekadar memindahkannya.
Berikutnya
Sekarang kamu bisa membaca JSON dan CSV. Keterampilan dunia nyata terakhir yang akan kita bahas adalah mengambil data lewat jaringan, di dokumen berikutnya tentang HTTP request dengan library requests.
Pertanyaan yang sering diajukan
Bagaimana cara membaca file CSV di Python?
Pakai modul bawaan csv. csv.reader memberimu setiap baris sebagai list berisi string; csv.DictReader memakai baris pertama sebagai header dan menghasilkan setiap baris sebagai dict. Buka file dengan newline='' agar Python tidak mengacaukan akhir baris: with open('data.csv', newline='') as f:.
Bagaimana cara menulis file CSV di Python?
Pasangkan csv.writer dengan file yang dibuka dalam mode tulis dan newline=''. Panggil writer.writerow([...]) untuk setiap baris atau writer.writerows([[...], [...]]) untuk sekumpulan baris. Untuk data berbentuk dict, pakai csv.DictWriter, yang menangani header secara otomatis.
Sebaiknya pakai modul csv atau pandas?
Pakai csv untuk membaca dan menulis yang cepat, file yang kamu proses baris per baris, dan saat kamu tidak ingin menambah dependensi. Pakai pandas kalau kamu perlu memfilter, mengelompokkan, atau menggabungkan data, atau kalau filenya cukup besar sehingga operasi tervektorisasi jadi penting. Keduanya menangani file yang sama; pilihannya tergantung apa yang kamu lakukan dengan data setelah dimuat.
Kenapa CSV-ku punya baris kosong di antara baris-barisnya di Windows?
Kamu membuka file tanpa newline=''. Modul csv menulis penanda akhir barisnya sendiri; tanpa argumen itu, Python menambahkan penanda ekstra di Windows. Selalu buka file CSV dengan open(path, newline=''), baik untuk membaca maupun menulis.