2011-09-07 10 views
14

Mam plik .csv: example.csv z 8000 kolumn x 40000 wierszy. Plik csv ma ​​nagłówek dla każdej kolumny. Wszystkie pola zawierają liczby całkowite z przedziału od 0 do 10. Kiedy próbuję wczytać ten plik z read.csv, okazuje się, że jest bardzo wolny. Jest również bardzo powolny, gdy dodaję parametr nrow = 100. Zastanawiam się, czy istnieje sposób przyspieszenia read.csv, lub użyć innej funkcji zamiast read.csv, aby załadować plik do pamięci jako macierz lub data.frame?read.csv bardzo wolno czyta pliki CSV z dużą liczbą kolumn

Z góry dziękuję.

+2

proszę udostępnić kod, którego używasz do read.csv - istnieje wiele opcji poprawiających wydajność, patrz? read.table – mdsumner

Odpowiedz

15

Jeśli CSV zawiera tylko liczby całkowite, należy użyć scan zamiast read.csv, ponieważ ?read.csv mówi:

‘read.table’ is not the right tool for reading large matrices, 
especially those with many columns: it is designed to read _data 
frames_ which may have columns of very different classes. Use 
‘scan’ instead for matrices. 

Ponieważ plik ma nagłówek, trzeba będzie skip=1, i prawdopodobnie będzie to szybciej, jeśli ustaw what=integer(). Jeśli musisz użyć parametru read.csv, a szybkość/zużycie pamięci są niepokojące, ustawienie argumentu colClasses jest ogromną pomocą.

+1

Możesz dodać nazwy kolumn z powrotem czytając pojedynczą linię z nagłówka jako wektora z funkcją 'readLines()' i modyfikującymi nazwy kolumn twojej macierzy. – John

+1

Dzięki. Właśnie znalazłem inną funkcję wrappera wykorzystującą funkcję scan(): read.matrix w pakiecie tseries. Twierdzi, że jest szybszy niż read.csv. – rninja

3

Jeśli często czytasz ten plik, warto zapisać go z R w formacie binarnym, używając funkcji save. Określenie compress=FALSE często powoduje szybsze ładowanie.

... Następnie można go załadować za pomocą funkcji (niespodzianka!) load.

d <- as.data.frame(matrix(1:1e6,ncol=1000)) 
write.csv(d, "c:/foo.csv", row.names=FALSE) 

# Load file with read.csv 
system.time(a <- read.csv("c:/foo.csv")) # 3.18 sec 

# Load file using scan 
system.time(b <- matrix(scan("c:/foo.csv", 0L, skip=1, sep=','), 
         ncol=1000, byrow=TRUE)) # 0.55 sec 

# Load (binary) file using load 
save(d, file="c:/foo.bin", compress=FALSE) 
system.time(load("c:/foo.bin")) # 0.09 sec 
+2

Czy szybkość kompresji zależy od wielu czynników i czy można ją przetestować na podstawie pliku/pliku/maszyny. Szybkość HD, szybkość procesora i stopień kompresji przyczyniają się do przyspieszenia ładowania skompresowanego lub nieskompresowanego pliku. Ogólnie rzecz biorąc, nieskompresowany może być szybszy, gdy prędkość dysku jest dobra, a szybkość procesora nie jest odwrotna, gdy jest odwrotnie w przypadku skompresowanego. Na przykład chciałbym użyć skompresowanego zapisu na dyskach flash USB na szybkim laptopie. – John

+0

@John - Dobra uwaga. Dlatego powiedziałem "często" ;-) – Tommy

8

Spróbuj użyć fread{data.table}. Jest to zdecydowanie najszybszy sposób odczytu .csv plików do R. Istnieje good benchmark here.

library(data.table) 

data <- fread("c:/data.csv") 

Jeśli chcesz, aby jeszcze szybciej, można również czytać tylko podzbiór kolumn chcesz użyć:

data <- fread("c:/data.csv", select = c("col1", "col2", "col3")) 
+0

Fread natychmiastowo zawiesza się na moich danych (ma nieco ponad milion kolumn) – shreyasgm

+0

To jest dziwne; Polecam odinstalować i ponownie zainstalować bibliotekę:'remove.packages ("data.table"); install.packages ("data.table") ". Jeśli problem będzie się powtarzał, możesz rozważyć otwarcie "sugestii" na stronie projektu https://github.com/Rdatatable/data.table/wiki –

3

także spróbować Hadley Wickhama readr pakiet:

library(readr) 
data <- read_csv("file.csv") 
Powiązane problemy