2014年9月13日 星期六

[R] 讀取大資料檔的效率比較:read.table vs freed


        最近在玩Kaggle(https://www.kaggle.com/)上的資料,還沒開始分析就碰到了問題:檔案太大讀不進來.原始檔案約11G的CSV檔,我的電腦只有8g(ram),而R的特性偏偏又是要將檔案讀到記憶體中做運算,根本無法進入下一步.
        R中的確是有幾個套件例如bigmemory或ff是在處理這樣的問題,但是光是讀檔案就耗掉半個一個小時,如果我只是想先看看資料長什麼樣子,這樣在時間成本考量上根本划不來.所以我退而求其次,既然資料量那麼大,那我不要全部讀取,只挑選部分資料讀進來總可以吧?這邊又有兩種分野:一種是讀取部分的row,一種是讀取部分的column.而我現在剛拿到資料,想進行初步的資料探索,我無法放棄任何一個欄位,所以我只能挑部分的row來做分析.這時候有兩種方法可以用:
        1. scan+read table
        2. fread(data.table packagehttp://cran.r-project.org/web/packages/data.table/data.table.pdf)
在面對大量資料這兩種做法都有人用,等一下來整理並且實測一下兩者的差異.(其實也可以透過RODBC連結資料庫,在資料庫上操作,但是因為我的電腦沒有裝ODBC所以暫不考慮)

        原本在找尋相關資料的時候是看到這裡(http://stackoverflow.com/questions/7327851/read-csv-is-extremely-slow-in-reading-csv-files-with-large-numbers-of-columns)說明如果read table本來就是效率不好的讀檔方式(畢竟要幫你自動判別欄位屬性),如果原始資料都是數值變項,直接用scan的方式將檔案掃成matrix就好.但是因為我的原始擋也有類別型變項所以這招行不通,所以改採用read.table的方式.

        但是當讀取的rows數量增加的時候,明顯感覺到效率的下降,所以我改用data table套件中的fread來執行,以下是兩者效率的比較:

rows = 10,000
read.table      1.8 秒
fread             102.4秒

rows =100,000
read.table         209.9 秒
fread                104.7秒

rows =1,000,000
read.table             >600 秒
fread                    116.8秒

從以上的比較可以發現,當資料檔不大的時候,read.table的效率並不差,剛開始我還誤以為fread沒有那麼神,但是當資料倍數成長時,fread的讀取速度並沒有明顯的差異,但read.table所需要的時間呈指數成長.

        順利把資料讀進來後,終於可以開始進行分析了T_T

補充資料:
http://stackoverflow.com/questions/1727772/quickly-reading-very-large-tables-as-dataframes-in-r
這個討論串也有比較不同的讀檔套件效率