Data yang diproses DataFrames.jl hampir selalu berpindah antara memori dan berkas. Topik ini membahas pembacaan serta penulisan berkas CSV dengan CSV.jl, putaran tulis dan baca format biner Arrow dengan Arrow.jl, dan arsip objek Julia dengan Serialization dari pustaka standar. Data contohnya kembali berupa nilai ujian enam siswa, sehingga isi setiap berkas mudah diperiksa ulang.
Berkas contoh dan pembacaan CSV#
Berkas contoh nilai_ujian.csv tersimpan di samping artikel dengan isinya sebagai berikut.
nama,kelas,nilai
Ali,7A,78
Budi,7A,85
Citra,7A,91
Dewi,7B,82
Eko,7B,74
Fajar,7B,88Fungsi CSV.read menerima jalur berkas dan tipe tujuannya. Argumen kedua DataFrame membuat hasilnya langsung berupa DataFrame, baris pertama berkas otomatis menjadi nama kolom, dan tipe setiap kolom dideteksi dari isinya. Argumen kata kunci stringtype = String membuat kolom teks bertipe String biasa. Tanpa argumen itu, CSV.jl memakai tipe InlineStrings yang dirancang untuk teks pendek.
using CSV, DataFrames
nilai = CSV.read("nilai_ujian.csv", DataFrame; stringtype = String)
println(nrow(nilai), " baris")
println(nilai.nama)
println(eltype(nilai.nilai))6 baris
["Ali", "Budi", "Citra", "Dewi", "Eko", "Fajar"]
Int64Keluaran menunjukkan enam baris terbaca, kolom nama berupa vektor string enam elemen, dan kolom nilai bertipe Int64. Tipe hasil deteksi ini layak diperiksa dengan eltype sebelum data diproses lebih jauh, karena tipe yang keliru biasanya baru tampak saat operasi berikutnya berjalan. Baris dan kolom yang terbaca selanjutnya dapat diperiksa dengan first(nilai, 3) maupun describe(nilai) dari DataFrames.jl, karena hasil CSV.read adalah DataFrame biasa yang mendukung seluruh operasi DataFrames.jl.
Menulis CSV dan pemisahnya#
Fungsi CSV.write menuliskan DataFrame ke jalur yang diberikan, lengkap dengan baris header otomatis. Pemisah kolomnya dideteksi otomatis saat pembacaan dan dapat dipaksa melalui argumen delim, baik pada CSV.write maupun CSV.read. Pemisah titik koma lazim dipakai pada berkas yang berasal dari lokal (locale) yang menggunakan koma sebagai tanda desimal. Contoh berikut menulis tabel persediaan ke direktori sementara, lalu menampilkan isi teks berkasnya sebelum membaca ulang.
using CSV, DataFrames
tabel = DataFrame(
barang = ["pensil", "buku", "penghapus"],
jumlah = [24, 10, 7],
)
dir = mktempdir()
jalur = joinpath(dir, "persediaan.csv")
CSV.write(jalur, tabel)
bacaan = CSV.read(jalur, DataFrame; stringtype = String)
println(read(jalur, String))
show(stdout, bacaan; allrows = true, allcols = true)barang,jumlah
pensil,24
buku,10
penghapus,7
3×2 DataFrame
Row │ barang jumlah
│ String Int64
─────┼───────────────────
1 │ pensil 24
2 │ buku 10
3 │ penghapus 7Isi teks berkas menunjukkan header barang,jumlah diikuti tiga baris data, dan hasil bacaannya kembali berupa DataFrame tiga baris. Fungsi read(jalur, String) membaca seluruh isi berkas sebagai satu string, sehingga format hasil tulisan dapat diperiksa secara langsung sebelum dipakai.
Berkas dengan pemisah lain ditangani dengan argumen yang sama. Pada contoh berikut, delim = ';' dinyatakan eksplisit di sisi penulisan maupun pembacaan. CSV.jl juga mendeteksi pemisah secara otomatis dari isi berkas, tetapi penegasan eksplisit membuat maksud skrip terbaca dan tidak terpengaruh oleh isi berkas yang tidak lazim.
using CSV, DataFrames
dir = mktempdir()
jalur = joinpath(dir, "data-titik-koma.csv")
CSV.write(jalur, DataFrame(nama = ["Ali", "Budi"], nilai = [78, 85]); delim = ';')
println(read(jalur, String))
bacaan = CSV.read(jalur, DataFrame; delim = ';', stringtype = String)
println(bacaan.nama)nama;nilai
Ali;78
Budi;85
["Ali", "Budi"]Berkas ditulis dengan pemisah titik koma, lalu kolom nama terbaca utuh sebagai vektor string. Pemisah yang dinyatakan pada kedua sisi memastikan penulis dan pembaca berkas memakai interpretasi yang sama.
Format Arrow#
Arrow adalah format biner berkolom yang menyimpan skema bersama datanya, sehingga tipe setiap kolom terjaga dari penulisan hingga pembacaan. Fungsi Arrow.write menuliskan tabel ke berkas .arrow, sedangkan Arrow.Table membacanya kembali. Ukuran berkasnya lebih kecil dan pembacaannya lebih cepat daripada teks CSV pada data besar, dan formatnya dibaca oleh banyak bahasa pemrograman sehingga cocok untuk pertukaran data. Kompresi tambahan tersedia melalui argumen compress berisi :lz4 atau :zstd.
using Arrow, DataFrames
tabel = DataFrame(
nama = ["Ali", "Budi", "Citra"],
kelas = ["7A", "7A", "7B"],
nilai = [78, 85, 91],
)
dir = mktempdir()
jalur = joinpath(dir, "nilai.arrow")
Arrow.write(jalur, tabel)
hasil = Arrow.Table(jalur)
println(eltype(hasil.nama))
println(eltype(hasil.kelas))
println(eltype(hasil.nilai))
println(hasil.nilai)String
String
Int64
[78, 85, 91]Tiga keluaran eltype menunjukkan String, String, dan Int64, persis seperti tipe kolom aslinya. Putaran ini menegaskan ciri utama Arrow, yaitu skema ikut tersimpan pada berkasnya, sehingga tipe kolom tidak perlu ditebak ulang saat membaca. Isi berkas .arrow tidak dapat dibaca langsung oleh editor teks karena berupa biner, sehingga pemeriksaan isinya dilakukan melalui Arrow.Table dan pencetakan kolomnya, sebagaimana nilai [78, 85, 91] pada keluaran.
Arsip objek dengan Serialization#
Pustaka standar Serialization menyimpan objek Julia apa pun ke berkas biner, termasuk Dict, struct, maupun DataFrame, melalui fungsi serialize dan deserialize. Putarannya memakai blok open dengan do, yaitu berkas dibuka untuk ditulis, diserialisasi, lalu ditutup otomatis setelah blok selesai. Formatnya khusus Julia dan bukan format pertukaran antarbahasa.
using DataFrames, Serialization
nilai = DataFrame(
nama = ["Ali", "Budi", "Citra", "Dewi", "Eko", "Fajar"],
kelas = ["7A", "7A", "7A", "7B", "7B", "7B"],
nilai = [78, 85, 91, 82, 74, 88],
)
dir = mktempdir()
jalur = joinpath(dir, "nilai.jls")
open(jalur, "w") do io
serialize(io, nilai)
end
kembali = open(jalur) do io
deserialize(io)
end
println(typeof(kembali))
println(nrow(kembali), " baris, jumlah nilai = ", sum(kembali.nilai))DataFrame
6 baris, jumlah nilai = 498Keluarannya menunjukkan objek yang kembali persis berupa DataFrame dengan enam baris, dan sum(kembali.nilai) menghitung 498 dari seluruh nilai. Representasi yang ditulis adalah internal Julia, sehingga struktur bersarang seperti vektor di dalam Dict pun utuh saat dibaca kembali. Arsip semacam ini cocok untuk hasil perhitungan menengah yang hanya dibaca kembali oleh Julia.
Contoh utuh: satu berkas, tiga format#
Skrip format-berkas.jl merangkai ketiga format pada satu putaran data, yaitu CSV sebagai pintu masuk, Arrow sebagai penyimpanan berkolom, dan Serialization sebagai arsip objek. Ketiganya menulis ke direktori sementara sehingga tidak meninggalkan sisa pada direktori proyek.
# format-berkas.jl
# Putaran data: CSV masuk, Arrow disimpan dan dibaca ulang, DataFrame diarsipkan dengan Serialization.
using Arrow, CSV, DataFrames, Serialization
nilai = CSV.read("nilai_ujian.csv", DataFrame; stringtype = String)
println("CSV : ", nrow(nilai), " baris, ", ncol(nilai), " kolom")
dir = mktempdir()
# tulis dan baca ulang format Arrow
jalur_arrow = joinpath(dir, "nilai.arrow")
Arrow.write(jalur_arrow, nilai)
hasil = Arrow.Table(jalur_arrow)
println("Arrow : ", nrow(hasil), " baris, eltype nilai = ", eltype(hasil.nilai))
# arsipkan objek DataFrame dengan Serialization dari pustaka standar
jalur_arsip = joinpath(dir, "nilai.jls")
open(jalur_arsip, "w") do io
serialize(io, nilai)
end
kembali = open(jalur_arsip) do io
deserialize(io)
end
println("Arsip : ", nrow(kembali), " baris, jumlah nilai = ", sum(kembali.nilai))CSV : 6 baris, 3 kolom
Arrow : 6 baris, eltype nilai = Int64
Arsip : 6 baris, jumlah nilai = 498Setiap baris keluaran menyatakan satu format beserta bukti keberhasilannya, mulai dari jumlah baris dan kolom yang terbaca dari CSV, tipe kolom yang terjaga pada Arrow, hingga jumlah nilai pada objek hasil deserialize. Urutan baris keluaran mengikuti urutan putarannya, yaitu CSV lebih dahulu, lalu Arrow, dan terakhir arsip. Seluruh berkas antara ditulis di dalam satu direktori mktempdir, sehingga pembersihannya cukup menghapus direktori itu. Pola tiga format ini lazim pada proyek data, yaitu CSV dari sumber luar, Arrow untuk kerja cepat, dan arsip biner untuk hasil antara.
Kesalahan umum#
Empat kesalahan berikut paling sering muncul saat format berkas dipraktikkan. Yang pertama dapat direproduksi pada contoh berikut.
using CSV, DataFrames
try
CSV.read("berkas-tidak-ada.csv", DataFrame)
catch e
println(typeof(e))
endArgumentError- Membaca berkas yang tidak ada.
CSV.readberhenti denganArgumentErrorsebagaimana contoh di atas, sehingga keberadaan berkas diuji denganisfilesebelum dibaca. - Memanggil
CSV.read(jalur)tanpa argumen kedua. Hasilnya berupaCSV.Fileyang belum merupakan DataFrame, sedangkan bentukCSV.read(jalur, DataFrame)langsung mengembalikan DataFrame. - Menukar pembaca antarformat. Berkas
.arrowdibaca denganArrow.Table, sedangkan berkas teks CSV dibaca denganCSV.read, karena pembaca yang keliru tidak memahami isinya. - Mengandalkan deteksi pemisah pada berkas yang teksnya memuat koma. Deteksi otomatis dapat salah memilih, sehingga argumen
delimyang eksplisit lebih aman.
Ringkasan#
CSV.read(jalur, DataFrame)membaca teks CSV dengan header otomatis, danCSV.writemenuliskannya kembali dengan argumendelimyang dapat dipaksa.- Arrow menyimpan data berkolom biner dengan skema tertanam, sehingga
eltypekolom hasil bacaan sama dengan aslinya. - Serialization menyimpan objek Julia apa pun, tetapi berkasnya hanya untuk Julia dan tidak dijamin terbaca antarversi.
mktempdirmenampung berkas sementara, sehingga seluruh contoh tidak meninggalkan sisa pada direktori proyek.
Referensi#
- CSV.jl — JuliaData
— Dokumentasi resmi
CSV.read,CSV.write, dan argumen pemisahnya. - Arrow.jl — Apache Arrow
— Dokumentasi resmi
Arrow.writedanArrow.Table. - Serialization — The Julia Language
— Dokumentasi resmi
serializedandeserialize.