2011-09-07 14 views
14

Ho un file .csv: example.csv con 8000 colonne x 40000 righe. Il file csv ha un'intestazione di stringa per ogni colonna. Tutti i campi contengono valori interi compresi tra 0 e 10. Quando provo a caricare questo file con read.csv, risulta estremamente lento. È anche molto lento quando aggiungo un parametro nrow = 100. Mi chiedo se c'è un modo per accelerare read.csv, o utilizzare qualche altra funzione invece di read.csv per caricare il file in memoria come matrice o data.frame?read.csv è estremamente lento nella lettura di file CSV con grandi numeri di colonne

Grazie in anticipo.

+2

per favore condividi il codice che stai usando per leggere.csv - ci sono molte opzioni per migliorare le prestazioni, vedi? read.table – mdsumner

risposta

15

Se il CSV contiene solo numeri interi, si dovrebbe usare scan invece di read.csv, dal momento che ?read.csv dice:

‘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. 

Dal momento che il file ha un'intestazione, avrete bisogno di skip=1, e probabilmente sarà più veloce se si impostare what=integer(). Se è necessario utilizzare read.csv e la velocità/il consumo di memoria sono un problema, l'impostazione dell'argomento colClasses è di grande aiuto.

+1

Puoi aggiungere i nomi delle tue colonne leggendo la singola riga della sua intestazione come vettore con la funzione 'readLines()' e modifica dei nomi delle colonne della tua matrice. – John

+1

Grazie. Ho appena trovato un'altra funzione wrapper che usa scan(): funzione read.matrix nel pacchetto tseries. Afferma che è più veloce di read.csv. – rninja

3

Se leggerai il file spesso, potrebbe valere la pena salvarlo da R in formato binario usando la funzione save. Specificare compress=FALSE spesso si traduce in tempi di caricamento più rapidi.

... È quindi possibile caricarlo con la (sorpresa!) Funzione 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

Se la compressione velocizza le cose dipende da più fattori e può essere testata su base/file/macchina. La velocità HD, la velocità della CPU e il livello di compressione raggiunto contribuiscono a determinare se il file compresso o non compresso è più veloce da caricare. Ma in generale, i non compressi possono essere più veloci quando la velocità dell'unità è buona e la velocità della CPU non è mentre è vero il contrario per la compressione. Ad esempio, preferirei utilizzare la scrittura compressa su unità flash USB su un laptop veloce. – John

+0

@ John - Buon punto. Ecco perché ho detto "spesso" ;-) – Tommy

8

Provare a utilizzare fread{data.table}. Questo è di gran lunga il modo più veloce per leggere i file .csv in R. C'è un good benchmark here.

library(data.table) 

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

Se si vuole rendere ancora più veloce, si può anche leggere solo il sottoinsieme di colonne che si desidera utilizzare:

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

fread si blocca istantaneamente sui miei dati (ha poco più di un milione di colonne) – shreyasgm

+0

Questo è strano; Ti consiglio di disinstallare e reinstallare la libreria:'remove.packages ("data.table"); install.packages ("data.table") '. Se il problema persiste, potresti prendere in considerazione l'idea di aprire una "falsa" sul sito web del progetto https://github.com/Rdatatable/data.table/wiki –

3

Provate anche readr pacchetto di Hadley Wickham:

library(readr) 
data <- read_csv("file.csv") 
Problemi correlati