Rでcsvの書き込みと読み込みの高速化
Rでcsvファイルの高速な書き込みと読み込みの方法。
よく使われているcsvの書き込みと読み込みの関数にwrite.csvとread.csvがある。
しかし、どちらの関数も実行時間が遅い。
私が良く使っている関数は、data.tableパッケージのfwriteとfreadです。
こっちの方が非常に高速。
では実際、実行時間にどれだけ差があるのだろう。
本記事では、それぞれの実行時間を比較する。
write.csvとfwriteの比較①
データを作成してcsvとして書き込みその時間を比較する。
データは1000行1000列の行列(サイズは約2MB)を100ファイル。
fwriteはmatrixを出力できないのでdata.frameに変換する。
時間の計測にはsystem.timeを使う。
library(data.table) nr=1000 nc=1000 N=100 #write.csvの計測 system.time( for(i in 1:N) { data=matrix(0,nrow=nr,ncol=nc) write.csv(data,"test.csv") } ) #fwriteの計測 system.time( for(i in 1:N) { data=data.frame(matrix(0,nrow=nr,ncol=nc)) fwrite(data,"test.csv") } )
結果
ユーザ | システム | 経過 | |
---|---|---|---|
write.csv | 63.262 | 1.294 | 67.953 |
fwrite | 12.520 | 0.606 | 13.677 |
read.csvとfreadの比較①
次に作成したデータを読み込みその時間を比較する。
N=100 #read.csvの計測 system.time( for(i in 1:N) { data=read.csv("test.csv") } ) #freadの計測 system.time( for(i in 1:N) { data=fread("test.csv") } )
結果
ユーザ | システム | 経過 | |
---|---|---|---|
read.csv | 40.435 | 0.699 | 41.940 |
fread | 4.631 | 0.094 | 4.743 |
write.csvとfwriteの比較②
データのサイズを変えてみる。
10000行10000列の行列(サイズは約200MB)を1ファイル。
library(data.table) nr=10000 nc=10000 N=1 #write.csvの計測 system.time( for(i in 1:N) { data=matrix(0,nrow=nr,ncol=nc) write.csv(data,"test.csv") } ) #fwriteの計測 system.time( for(i in 1:N) { data=data.frame(matrix(0,nrow=nr,ncol=nc)) fwrite(data,"test.csv") } )
結果
ユーザ | システム | 経過 | |
---|---|---|---|
write.csv | 74.812 | 1.702 | 79.110 |
fwrite | 10.129 | 1.656 | 8.006 |
read.csvとfreadの比較②
再び作成したデータを読み込みその時間を比較する。
N=1 #read.csvの計測 system.time( for(i in 1:N) { data=read.csv("test.csv") } ) #freadの計測 system.time( for(i in 1:N) { data=fread("test.csv") } )
結果
ユーザ | システム | 経過 | |
---|---|---|---|
read.csv | 46.540 | 1.825 | 49.908 |
fread | 4.920 | 0.187 | 5.295 |
まとめ
2パターンで試したが、どちらのパターンでもwrite.csv、read.csvとfwrite、freadとの間に、明らかな実行時間の差があった。
差が小さい時では約5倍、大きい時では約10倍。
本当は何回か実験するべきだろうけど、これだけ差があることがわかれば何回もする必要はない。なにより面倒。
fwriteとfreadの方が明らかに早いが、注意点もある。
fwriteが出力できる型はdata.frameとdata.tableであり、matrixは出力できない。
freadはデフォルトではdata.table型で読み込むのでdata.frame型で読み込むなら、引数にdata.table=Fとする必要がある。
data.table型については、以下のリンクを参照。
qiita.com