Saya memiliki tabel yang sangat besar (30 juta baris) yang ingin saya muat sebagai dataframe di R. read.table()
memiliki banyak fitur yang mudah, tetapi sepertinya ada banyak logika dalam implementasi yang akan memperlambat segalanya. Dalam kasus saya, saya berasumsi saya tahu jenis kolom sebelumnya, tabel tidak berisi judul kolom atau nama baris, dan tidak memiliki karakter patologis yang harus saya khawatirkan.
Saya tahu bahwa membaca dalam tabel sebagai daftar menggunakan scan()
bisa sangat cepat, misalnya:
datalist <- scan('myfile',sep='\t',list(url='',popularity=0,mintime=0,maxtime=0)))
Tetapi beberapa upaya saya untuk mengonversikan ini ke dataframe nampak mengurangi kinerja di atas dengan faktor 6:
df <- as.data.frame(scan('myfile',sep='\t',list(url='',popularity=0,mintime=0,maxtime=0))))
Apakah ada cara yang lebih baik untuk melakukan ini? Atau mungkin pendekatan yang sangat berbeda untuk masalah ini?
feather
. Untuk membaca datafeather
jauh lebih cepat daripadafread
. Sebagai contoh pada dataset 4GB yang baru saya muatread_feather
sekitar 4,5 kali lebih cepat daripadafread
. Untuk menyimpan datafwrite
masih lebih cepat. blog.dominodatalab.com/the-r-data-io-shootoutfeather
lebih cepat untuk membaca tetapi menggunakan lebih banyak ruang penyimpanan.feather
adalah opsi yang baik. Jika Anda hanya peduli untuk dapat membaca data Anda dalam R,rds
lebih disukai.Berikut adalah contoh yang memanfaatkan
fread
daridata.table
1.8.7Contohnya datang dari halaman bantuan ke
fread
, dengan timing di windows XP Core 2 duo E8400 saya.tabel read.tabel standar
baca tabel dioptimalkan
ketakutan
sqldf
ff / ffdf
Singkatnya:
sumber
fread
. Sudah mencoba membacanya dengan fungsi dasar R dan butuh sekitar 15 jam.readr
?fread
memiliki beberapa pesaing nyata sekarang, dapat bermanfaat untuk menambah tolok ukur untukfread
penggunaan yang dioptimalkan - menentukancolClasses
, dll.Awalnya saya tidak melihat pertanyaan ini dan mengajukan pertanyaan serupa beberapa hari kemudian. Saya akan menjawab pertanyaan saya sebelumnya, tetapi saya pikir saya akan menambahkan jawaban di sini untuk menjelaskan bagaimana saya
sqldf()
melakukan ini.Ada sedikit diskusi tentang cara terbaik untuk mengimpor 2GB atau lebih data teks ke dalam bingkai data R. Kemarin saya menulis posting blog tentang menggunakan
sqldf()
untuk mengimpor data ke SQLite sebagai area pementasan, dan kemudian mengisapnya dari SQLite ke R. Ini bekerja sangat baik untuk saya. Saya dapat menarik 2GB (3 kolom, baris 40mm) data dalam <5 menit. Sebaliknya,read.csv
perintah itu berjalan sepanjang malam dan tidak pernah selesai.Ini kode pengujian saya:
Siapkan data uji:
Saya memulai ulang R sebelum menjalankan rutin impor berikut:
Saya membiarkan baris berikut berjalan sepanjang malam tetapi tidak pernah selesai:
sumber
Anehnya, tidak ada yang menjawab bagian bawah pertanyaan selama bertahun-tahun meskipun ini adalah yang penting -
data.frame
hanya daftar dengan atribut yang tepat, jadi jika Anda memiliki data besar Anda tidak ingin menggunakanas.data.frame
atau serupa untuk daftar. Jauh lebih cepat untuk "mengubah" daftar menjadi bingkai data di tempat:Ini tidak membuat salinan data sehingga langsung (tidak seperti semua metode lain). Diasumsikan bahwa Anda telah menetapkan
names()
pada daftar yang sesuai.[Adapun untuk memuat data besar ke R - secara pribadi, saya membuangnya dengan kolom ke file biner dan menggunakan
readBin()
- yang sejauh ini merupakan metode tercepat (selain mmapping) dan hanya dibatasi oleh kecepatan disk. Parsing file ASCII secara inheren lambat (bahkan dalam C) dibandingkan dengan data biner.]sumber
tracmem
menyarankan ituattr<-
danclass<-
membuat salinan secara internal.bit::setattr
ataudata.table::setattr
tidak.df=scan(...); names(df)=...; attr...; class...
- lihattracemem()
(diuji dalam R 2.15.2)Ini sebelumnya ditanyakan pada R-Help , jadi itu layak ditinjau.
Satu saran ada untuk menggunakan
readChar()
dan kemudian melakukan manipulasi string pada hasil denganstrsplit()
dansubstr()
. Anda dapat melihat logika yang terlibat dalam readChar jauh lebih sedikit daripada read.table.Saya tidak tahu apakah memori menjadi masalah di sini, tetapi Anda mungkin juga ingin melihat pada paket HadoopStreaming . Ini menggunakan Hadoop , yang merupakan kerangka kerja MapReduce yang dirancang untuk menangani set data besar. Untuk ini, Anda akan menggunakan fungsi hsTableReader. Ini adalah contoh (tetapi memiliki kurva belajar untuk mempelajari Hadoop):
Ide dasar di sini adalah memecah impor data menjadi potongan-potongan. Anda bahkan dapat melangkah lebih jauh dengan menggunakan salah satu kerangka kerja paralel (misalnya salju) dan menjalankan impor data secara paralel dengan mensegmentasi file, tetapi kemungkinan besar untuk kumpulan data besar yang tidak akan membantu karena Anda akan mengalami kendala memori, itulah sebabnya pengurangan peta adalah pendekatan yang lebih baik.
sumber
Alternatifnya adalah menggunakan
vroom
paket. Sekarang di CRAN.vroom
tidak memuat seluruh file, itu mengindeks tempat setiap catatan berada, dan dibaca nanti saat Anda menggunakannya.Lihat Pengantar vroom , Mulailah dengan vroom dan tolok ukur vroom .
Gambaran dasar adalah bahwa pembacaan awal file besar, akan jauh lebih cepat, dan modifikasi selanjutnya pada data mungkin sedikit lebih lambat. Jadi tergantung pada apa yang Anda gunakan, itu bisa menjadi pilihan terbaik.
Lihat contoh sederhana dari tolok ukur vroom di bawah ini, bagian utama yang harus dilihat adalah waktu baca super cepat, tetapi operasi yang sedikit menabur seperti agregat dll.
sumber
Poin tambahan kecil yang layak disebut. Jika Anda memiliki file yang sangat besar Anda dapat dengan cepat menghitung jumlah baris (jika tidak ada header) menggunakan (di mana
bedGraph
nama file Anda di direktori kerja Anda):Anda kemudian dapat menggunakannya di
read.csv
,read.table
...sumber
Sering kali saya pikir itu hanya praktik yang baik untuk menyimpan basis data yang lebih besar di dalam basis data (misalnya Postgres). Saya tidak menggunakan sesuatu yang terlalu besar dari (nrow * ncol) ncell = 10M, yang cukup kecil; tetapi saya sering menemukan bahwa saya ingin R membuat dan menahan grafik intensif memori hanya ketika saya meminta dari banyak basis data. Di masa depan laptop 32 GB, beberapa jenis masalah memori ini akan hilang. Namun daya pikat menggunakan database untuk menyimpan data dan kemudian menggunakan memori R untuk hasil kueri yang dihasilkan dan grafik masih mungkin berguna. Beberapa keunggulannya adalah:
(1) Data tetap dimuat di basis data Anda. Anda cukup menyambungkan kembali dalam pgadmin ke database yang Anda inginkan saat menghidupkan kembali laptop Anda.
(2) Memang benar R dapat melakukan banyak operasi statistik dan grafik yang lebih baik daripada SQL. Tapi saya pikir SQL lebih baik dirancang untuk query data dalam jumlah besar daripada R.
sumber
Saya membaca data dengan sangat cepat menggunakan
arrow
paket baru . Tampaknya berada pada tahap yang cukup awal.Secara khusus, saya menggunakan format kolom parket . Ini mengonversi kembali ke
data.frame
dalam R, tetapi Anda bisa mendapatkan speedup lebih dalam jika tidak. Format ini nyaman karena dapat digunakan dari Python juga.Kasus penggunaan utama saya untuk ini adalah pada server RShiny yang cukup terkendali. Untuk alasan ini, saya lebih suka menyimpan data yang melekat pada Aplikasi (yaitu, keluar dari SQL), dan karena itu memerlukan ukuran file kecil serta kecepatan.
Artikel tertaut ini memberikan tolok ukur dan tinjauan umum yang baik. Saya telah mengutip beberapa poin menarik di bawah ini.
https://ursalabs.org/blog/2019-10-columnar-perf/
Ukuran file
Baca Kecepatan
Tes Independen
Saya melakukan beberapa pembandingan independen pada set data simulasi 1.000.000 baris. Pada dasarnya saya mengocok banyak hal di sekitar untuk mencoba menantang kompresi. Saya juga menambahkan bidang teks pendek kata-kata acak dan dua faktor simulasi.
Data
Baca dan tulis
Menulis data itu mudah.
Membaca data juga mudah.
Saya diuji membaca data ini terhadap beberapa opsi yang bersaing, dan memang mendapatkan hasil yang sedikit berbeda dibandingkan dengan artikel di atas, yang diharapkan.
File ini jauh dari ukuran artikel benchmark, jadi mungkin itulah bedanya.
Tes
as_data_frame = FALSE
)arrow
)feather
)Pengamatan
Untuk file khusus ini,
fread
sebenarnya sangat cepat. Saya suka ukuran file kecil dariparquet2
tes yang sangat terkompresi . Saya dapat menginvestasikan waktu untuk bekerja dengan format data asli daripadadata.frame
jika saya benar-benar perlu mempercepat.Ini
fst
juga pilihan yang bagus. Saya akan menggunakanfst
format yang sangat terkompresi atau sangat terkompresiparquet
tergantung pada apakah saya memerlukan kecepatan atau ukuran file trade off.sumber
Alih-alih read.table konvensional saya merasa takut adalah fungsi yang lebih cepat. Menentukan atribut tambahan seperti hanya memilih kolom yang diperlukan, menentukan colclass dan string karena faktor akan mengurangi waktu yang diperlukan untuk mengimpor file.
sumber
Saya sudah mencoba semuanya di atas dan [readr] [1] membuat pekerjaan terbaik. Saya hanya memiliki RAM 8GB
Loop untuk 20 file, masing-masing 5gb, 7 kolom:
sumber