Lettura rapida di tabelle molto grandi come frame di dati


504

Ho tabelle molto grandi (30 milioni di righe) che vorrei caricare come frame di dati in R. read.table()ha molte funzioni convenienti, ma sembra che ci sia molta logica nell'implementazione che rallenterebbe le cose. Nel mio caso, presumo di conoscere i tipi di colonne in anticipo, la tabella non contiene intestazioni di colonna o nomi di riga e non ha caratteri patologici di cui devo preoccuparmi.

So che leggere in una tabella come un elenco usando scan()può essere abbastanza veloce, ad esempio:

datalist <- scan('myfile',sep='\t',list(url='',popularity=0,mintime=0,maxtime=0)))

Ma alcuni dei miei tentativi di convertire questo in un frame di dati sembrano ridurre le prestazioni di cui sopra di un fattore 6:

df <- as.data.frame(scan('myfile',sep='\t',list(url='',popularity=0,mintime=0,maxtime=0))))

C'è un modo migliore per farlo? O forse un approccio completamente diverso al problema?

Risposte:


426

Un aggiornamento, diversi anni dopo

Questa risposta è vecchia e R è passato avanti. La modifica read.tableper correre un po 'più veloce ha un piccolo vantaggio prezioso. Le tue opzioni sono:

  1. Utilizzo vroomdal pacchetto tidyverse vroomper l'importazione di dati da file CSV / delimitati da tabulazioni direttamente in una tabella R.

  2. Utilizzare freadin data.tableper importare dati da file CSV / delimitati da tabulazioni direttamente in R. Vedere la risposta di mnel .

  3. Utilizzo read_tablein readr(su CRAN da aprile 2015). Funziona molto come freadsopra. Il file Leggimi nel link spiega la differenza tra le due funzioni ( readrattualmente afferma di essere "1,5-2 volte più lento" di data.table::fread).

  4. read.csv.rawda iotoolsfornisce una terza opzione per leggere rapidamente i file CSV.

  5. Cerca di archiviare quanti più dati possibile nei database anziché nei file flat. (Oltre ad essere un miglior supporto di archiviazione permanente, i dati vengono passati da e verso R in un formato binario, che è più veloce.) read.csv.sqlNel sqldfpacchetto, come descritto nella risposta di JD Long , importa i dati in un database temporaneo SQLite e poi li legge in R. Vedi anche: il RODBCpacchetto e il retro dipende dalla sezione della pagina del DBIpacchetto . MonetDB.Rti dà un tipo di dati che finge di essere un frame di dati ma è in realtà un MonetDB sottostante, aumentando le prestazioni. Importa i dati con la sua monetdb.read.csvfunzione. dplyrti consente di lavorare direttamente con i dati memorizzati in diversi tipi di database.

  6. La memorizzazione di dati in formati binari può anche essere utile per migliorare le prestazioni. Utilizzare saveRDS/ readRDS(vedi sotto), i pacchetti h5o rhdf5per il formato HDF5 o write_fst/ read_fstdal fstpacchetto.


La risposta originale

Ci sono un paio di cose semplici da provare, sia che tu usi read.table o scan.

  1. Imposta nrows= il numero di record nei tuoi dati ( nmaxin scan).

  2. Assicurarsi che comment.char=""per disattivare l'interpretazione dei commenti.

  3. Definire esplicitamente le classi di ogni colonna usando colClassesin read.table.

  4. L'impostazione multi.line=FALSEpuò anche migliorare le prestazioni nella scansione.

Se nessuna di queste cose funziona, usa uno dei pacchetti di profilazione per determinare quali linee stanno rallentando le cose. Forse puoi scrivere una versione ridotta diread.table base ai risultati.

L'altra alternativa è filtrare i dati prima di leggerli in R.

In alternativa, se il problema è che devi leggerlo regolarmente, quindi utilizzare questi metodi per leggere i dati una volta, quindi salvare il frame di dati come BLOB binario con save saveRDS, quindi la prossima volta puoi recuperarlo più velocemente con load readRDS.


4
Grazie per i suggerimenti Richie. Ho fatto un piccolo test e sembra che le prestazioni ottenute con l'uso delle opzioni nrow e colClasses per read.table siano piuttosto modeste. Ad esempio, la lettura di una tabella di righe di ~ 7 M richiede 78 secondi senza le opzioni e 67 secondi con le opzioni. (nota: la tabella ha 1 colonna di caratteri, 4 colonne intere e ho letto usando comment.char = '' e stringsAsFactors = FALSE). L'uso di save () e load () quando possibile è un ottimo suggerimento: una volta memorizzato con save (), la stessa tabella richiede solo 12 secondi per essere caricata.
Eytan,

2
Il pacchetto "feather" ha un nuovo formato binario che funziona bene con i frame di dati panda di Python
rsoren

4
Penso che forse devi aggiornare di nuovo il tuo post per quanto riguarda il pacchetto feather. Per leggere i dati featherè molto più veloce di fread. Ad esempio, su un set di dati da 4 GB che ho appena caricato read_featherera circa 4,5 volte più veloce di fread. Per il salvataggio dei dati fwriteè ancora più veloce. blog.dominodatalab.com/the-r-data-io-shootout
Z boson

2
Ma le dimensioni dei file sono molto più grandi per piuma che con RDS. Non penso che supporti la compressione. Il file RDS è 216 MB e il file piuma è 4 GB. Quindi featherè più veloce per la lettura ma utilizza molto più spazio di archiviazione.
Bosone Z

@Zboson Se è necessario archiviare un frame di dati in un file a cui è possibile accedere sia da R che da Python, questa featherè una buona opzione. Se ti interessa solo poter leggere i tuoi dati in R, rdsè preferibile.
Richie Cotton,

279

Ecco un esempio che utilizza freaddalla data.table1.8.7

Gli esempi provengono dalla pagina di aiuto per fread, con i tempi sul mio Windows XP Core 2 duo E8400.

library(data.table)
# Demo speedup
n=1e6
DT = data.table( a=sample(1:1000,n,replace=TRUE),
                 b=sample(1:1000,n,replace=TRUE),
                 c=rnorm(n),
                 d=sample(c("foo","bar","baz","qux","quux"),n,replace=TRUE),
                 e=rnorm(n),
                 f=sample(1:1000,n,replace=TRUE) )
DT[2,b:=NA_integer_]
DT[4,c:=NA_real_]
DT[3,d:=NA_character_]
DT[5,d:=""]
DT[2,e:=+Inf]
DT[3,e:=-Inf]

read.table standard

write.table(DT,"test.csv",sep=",",row.names=FALSE,quote=FALSE)
cat("File size (MB):",round(file.info("test.csv")$size/1024^2),"\n")    
## File size (MB): 51 

system.time(DF1 <- read.csv("test.csv",stringsAsFactors=FALSE))        
##    user  system elapsed 
##   24.71    0.15   25.42
# second run will be faster
system.time(DF1 <- read.csv("test.csv",stringsAsFactors=FALSE))        
##    user  system elapsed 
##   17.85    0.07   17.98

read.table ottimizzato

system.time(DF2 <- read.table("test.csv",header=TRUE,sep=",",quote="",  
                          stringsAsFactors=FALSE,comment.char="",nrows=n,                   
                          colClasses=c("integer","integer","numeric",                        
                                       "character","numeric","integer")))


##    user  system elapsed 
##   10.20    0.03   10.32

fread

require(data.table)
system.time(DT <- fread("test.csv"))                                  
 ##    user  system elapsed 
##    3.12    0.01    3.22

sqldf

require(sqldf)

system.time(SQLDF <- read.csv.sql("test.csv",dbname=NULL))             

##    user  system elapsed 
##   12.49    0.09   12.69

# sqldf as on SO

f <- file("test.csv")
system.time(SQLf <- sqldf("select * from f", dbname = tempfile(), file.format = list(header = T, row.names = F)))

##    user  system elapsed 
##   10.21    0.47   10.73

ff / ffdf

 require(ff)

 system.time(FFDF <- read.csv.ffdf(file="test.csv",nrows=n))   
 ##    user  system elapsed 
 ##   10.85    0.10   10.99

In sintesi:

##    user  system elapsed  Method
##   24.71    0.15   25.42  read.csv (first time)
##   17.85    0.07   17.98  read.csv (second time)
##   10.20    0.03   10.32  Optimized read.table
##    3.12    0.01    3.22  fread
##   12.49    0.09   12.69  sqldf
##   10.21    0.47   10.73  sqldf on SO
##   10.85    0.10   10.99  ffdf

43
Ottima risposta, e il benchmarking vale in altri contesti. Basta leggere in un file da 4 GB in ben meno di un minuto con fread. Avevo provato a leggerlo con le funzioni di base R e ci sono volute circa 15 ore.
Ari B. Friedman,

1
il mio benchmark suggerisce vantaggi di velocità ancora maggiori per read.csv in data.table. nota che data.table non è R standard, ma (purtroppo) "solo" ben condiviso dai suoi creatori su CRAN. non è nemmeno considerato abbastanza standard da rendere l'elenco comune dei pacchetti R, tanto meno qualificarsi come sostituto dei frame di dati. ha molti vantaggi, ma anche alcuni aspetti molto controintuitivi. potresti voler usare as.data.frame (fread.csv ("test.csv")) con il pacchetto per tornare al mondo del frame di dati R standard.
ivo Welch,

3
@mnel potresti rieseguire il benchmark e includerlo readr?
jangorecki,

2
Secondo @jangorecki. Inoltre, dato che ora freadha alcuni veri concorrenti, potrebbe essere utile aggiungere parametri di riferimento per un freadutilizzo ottimizzato - specificando colClasses, ecc.
MichaelChirico,

1
@jangorecji @ MichaelChirico il codice fornito è interamente riproducibile, quindi è semplice simulare la lettura ... rieseguendo il codice, sulla mia macchina il tempo trascorso è due volte più veloce se non di più per la maggior parte dei risultati anche se lo sto eseguendo su una rete (e versioni ben aggiornate come è ora) ... e con readr sono a 7 secondi ma anche meno di un secondo quando corro una seconda volta (0,66 secondi), sospetto che ci sia un po 'di cache o un collo di bottiglia nella rete. la ricerca della soluzione più veloce mostrata qui è a 2 secondi dalla mia parte per il confronto (prima volta a 8,69 secondi) per qualche motivo più lento)
R. Prost

249

Inizialmente non ho visto questa domanda e ho fatto una domanda simile qualche giorno dopo. Ho intenzione di prendere la mia domanda precedente, ma ho pensato di aggiungere una risposta qui per spiegare come ero solito sqldf()fare questo.

C'è stato un po 'di discussione sul modo migliore per importare 2 GB o più di dati di testo in un frame di dati R. Ieri ho scritto un post sul blog sull'utilizzo sqldf()per importare i dati in SQLite come area di gestione temporanea, e poi succhiarli da SQLite in R. Questo funziona davvero bene per me. Sono stato in grado di estrarre 2 GB (3 colonne, file da 40 mm) di dati in <5 minuti. Al contrario, il read.csvcomando è stato eseguito tutta la notte e non è mai stato completato.

Ecco il mio codice di prova:

Imposta i dati del test:

bigdf <- data.frame(dim=sample(letters, replace=T, 4e7), fact1=rnorm(4e7), fact2=rnorm(4e7, 20, 50))
write.csv(bigdf, 'bigdf.csv', quote = F)

Ho riavviato R prima di eseguire la seguente routine di importazione:

library(sqldf)
f <- file("bigdf.csv")
system.time(bigdf <- sqldf("select * from f", dbname = tempfile(), file.format = list(header = T, row.names = F)))

Ho lasciato correre la seguente riga per tutta la notte ma non è mai stata completata:

system.time(big.df <- read.csv('bigdf.csv'))

1
Ciao. In che modo lo usi come input per altri pacchetti come zoo, progettato per essere utilizzato contemporaneamente con tutti i dati?
skan

@skan l'oggetto finale è un frame di dati. Quindi devi convertirlo in un oggetto zoo per usarlo con lo zoo. Guarda gli esempi nei documenti dello zoo per le illustrazioni.
JD Long

@JD Long. Ciao, il problema è che quando lo converti in un oggetto zoo cerca di adattarlo alla memoria. Se è troppo grande, produce un errore. E se anche il risultato dell'oggetto zoo (ad esempio un'aggregazione di due serie) dovrebbe essere anche un oggetto sql o ff.
skan

Non so cosa c'è che non va in sqldf. Ho creato un semplice file da 1 GB su disco (con 2 colonne numeriche) e ho usato DTSQL <- read.csv.sql ("f2.txt", dbname = tempfile ()) e tenta di caricare tutti i dati in memoria. Domani proverò invece ff e revoscaler.
skan

1
@quanto m è migliaia, quindi mm è migliaia migliaia o milioni. Probabilmente avrei dovuto capitalizzarlo come MM. Ma trovo che quasi ogni milione di abbreviazioni può confondere qualcuno se hai un pubblico abbastanza diversificato. Nel mio tentativo di essere eccessivamente prolisso, mi dispiace di averlo reso più confuso! accountingcoach.com/blog/what-does-m-and-mm-stand-for
JD Long

73

Stranamente, nessuno ha risposto alla parte inferiore della domanda per anni, anche se questo è importante: si data.frametratta semplicemente di elenchi con gli attributi giusti, quindi se si dispone di dati di grandi dimensioni che non si desidera utilizzare as.data.frameo simili per un elenco. È molto più veloce semplicemente "trasformare" un elenco in un frame di dati sul posto:

attr(df, "row.names") <- .set_row_names(length(df[[1]]))
class(df) <- "data.frame"

Questo non fa alcuna copia dei dati, quindi è immediato (a differenza di tutti gli altri metodi). Presuppone che tu abbia già impostato di conseguenza names()l'elenco.

[Per quanto riguarda il caricamento di dati di grandi dimensioni in R - personalmente, li scarico per colonna in file binari e utilizzo readBin()- questo è di gran lunga il metodo più veloce (diverso da mmapping) ed è limitato solo dalla velocità del disco. L'analisi dei file ASCII è intrinsecamente lenta (anche in C) rispetto ai dati binari.]


6
L'utilizzo tracmemsuggerisce che attr<-e class<-fare copie internamente. bit::setattro data.table::setattrno.
mnel

6
Forse hai usato l'ordine sbagliato? Se non si utilizza alcuna copia df=scan(...); names(df)=...; attr...; class..., consultare tracemem()(testato in R 2.15.2)
Simon Urbanek,

3
Puoi approfondire come scaricare i dati di grandi dimensioni per colonna in file binari?
dabsingh,

32

Questo è stato precedentemente richiesto su R-Help , quindi vale la pena esaminarlo.

Un suggerimento era di usare readChar()e poi fare manipolazione di stringhe sul risultato con strsplit()e substr(). Puoi vedere che la logica coinvolta in readChar è molto meno di read.table.

Non so se la memoria è un problema qui, ma potresti anche dare un'occhiata al pacchetto HadoopStreaming . Questo utilizza Hadoop , che è un framework MapReduce progettato per gestire set di dati di grandi dimensioni. Per questo, useresti la funzione hsTableReader. Questo è un esempio (ma ha una curva di apprendimento per imparare Hadoop):

str <- "key1\t3.9\nkey1\t8.9\nkey1\t1.2\nkey1\t3.9\nkey1\t8.9\nkey1\t1.2\nkey2\t9.9\nkey2\"
cat(str)
cols = list(key='',val=0)
con <- textConnection(str, open = "r")
hsTableReader(con,cols,chunkSize=6,FUN=print,ignoreKey=TRUE)
close(con)

L'idea di base qui è quella di spezzare l'importazione dei dati in blocchi. Potresti persino arrivare a utilizzare uno dei framework paralleli (ad esempio snow) ed eseguire l'importazione dei dati in parallelo segmentando il file, ma molto probabilmente per set di dati di grandi dimensioni che non ti aiuteranno poiché ti imbatterai in vincoli di memoria, ecco perché la riduzione delle mappe è un approccio migliore.


Ho appena fatto un test rapido e readChar sembra essere molto più veloce di readLines per qualche motivo inspiegabile. Tuttavia, è ancora lento come peccato rispetto a un semplice test C. Al semplice compito di leggere 100 mega, R è circa 5-10 volte più lento di C
Jonathan Chang,

1
Non capisco il tuo punto. Il punto di Hadoop è gestire dati molto grandi, che è la questione.
Shane,

1
Nonostante il nome, hsTableReader non ha nulla a che fare con Hadoop di per sé, è per l'elaborazione di grandi quantità di dati. Legge da con, un blocco di righe alla volta e passa ciascun blocco come data.frame a FUN per l'elaborazione. Con ignoreKey = FALSE, esegue alcuni raggruppamenti extra per chiave (la voce nella prima colonna), che è rilevante per gli approcci Mappa / Riduci.
David

Ciao. Come useresti questi dati di Hadoop come input per altri pacchetti come zoo, progettati per essere usati contemporaneamente con tutti i dati?
skan

10

Un'alternativa è usare il vroompacchetto. Ora su CRAN. vroomnon carica l'intero file, indicizza dove si trova ogni record e viene letto in seguito quando lo si utilizza.

Paghi solo ciò che usi.

Vedere Introduzione a Vroom , Introduzione a Vroom e ai parametri di riferimento di Vroom .

La panoramica di base è che la lettura iniziale di un file enorme sarà molto più veloce e le successive modifiche ai dati potrebbero essere leggermente più lente. Quindi, a seconda di quale sia il tuo utilizzo, potrebbe essere l'opzione migliore.

Vedi un esempio semplificato dai benchmark di Vroom di seguito, le parti chiave da vedere sono i tempi di lettura super veloci, ma operazioni leggermente seminatrici come aggregate ecc.

package                 read    print   sample   filter  aggregate   total
read.delim              1m      21.5s   1ms      315ms   764ms       1m 22.6s
readr                   33.1s   90ms    2ms      202ms   825ms       34.2s
data.table              15.7s   13ms    1ms      129ms   394ms       16.3s
vroom (altrep) dplyr    1.7s    89ms    1.7s     1.3s    1.9s        6.7s

5

Un piccolo punto aggiuntivo degno di nota. Se hai un file molto grande puoi calcolare al volo il numero di righe (se non c'è intestazione) usando (dove si bedGraphtrova il nome del tuo file nella directory di lavoro):

>numRow=as.integer(system(paste("wc -l", bedGraph, "| sed 's/[^0-9.]*\\([0-9.]*\\).*/\\1/'"), intern=T))

È quindi possibile utilizzare quello in read.csv, read.table...

>system.time((BG=read.table(bedGraph, nrows=numRow, col.names=c('chr', 'start', 'end', 'score'),colClasses=c('character', rep('integer',3)))))
   user  system elapsed 
 25.877   0.887  26.752 
>object.size(BG)
203949432 bytes

4

Spesso penso che sia una buona pratica conservare database più grandi all'interno di un database (ad esempio Postgres). Non uso nulla di troppo grande di (nrow * ncol) ncell = 10M, che è piuttosto piccolo; ma trovo spesso che voglio R per creare e conservare grafici ad alta intensità di memoria solo mentre eseguo query da più database. Nel futuro dei laptop da 32 GB, alcuni di questi tipi di problemi di memoria scompariranno. Ma il fascino di usare un database per contenere i dati e quindi usare la memoria di R per i risultati e i grafici delle query risultanti può essere ancora utile. Alcuni vantaggi sono:

(1) I dati rimangono caricati nel database. Ti riconnetti semplicemente in pgadmin ai database desiderati quando riaccendi il laptop.

(2) È vero che R può fare molte più operazioni statistiche e grafiche di SQL. Ma penso che SQL sia meglio progettato per interrogare grandi quantità di dati rispetto a R.

# Looking at Voter/Registrant Age by Decade

library(RPostgreSQL);library(lattice)

con <- dbConnect(PostgreSQL(), user= "postgres", password="password",
                 port="2345", host="localhost", dbname="WC2014_08_01_2014")

Decade_BD_1980_42 <- dbGetQuery(con,"Select PrecinctID,Count(PrecinctID),extract(DECADE from Birthdate) from voterdb where extract(DECADE from Birthdate)::numeric > 198 and PrecinctID in (Select * from LD42) Group By PrecinctID,date_part Order by Count DESC;")

Decade_RD_1980_42 <- dbGetQuery(con,"Select PrecinctID,Count(PrecinctID),extract(DECADE from RegistrationDate) from voterdb where extract(DECADE from RegistrationDate)::numeric > 198 and PrecinctID in (Select * from LD42) Group By PrecinctID,date_part Order by Count DESC;")

with(Decade_BD_1980_42,(barchart(~count | as.factor(precinctid))));
mtext("42LD Birthdays later than 1980 by Precinct",side=1,line=0)

with(Decade_RD_1980_42,(barchart(~count | as.factor(precinctid))));
mtext("42LD Registration Dates later than 1980 by Precinct",side=1,line=0)

3

Sto leggendo i dati molto rapidamente utilizzando il nuovo arrow pacchetto. Sembra essere in una fase abbastanza precoce.

In particolare, sto usando il formato colonnare del parquet . Questo si converte in adata.frame in R, ma puoi ottenere accelerazioni ancora più profonde se non lo fai. Questo formato è comodo in quanto può essere utilizzato anche da Python.

Il mio caso d'uso principale per questo è su un server RShiny abbastanza contenuto. Per questi motivi, preferisco mantenere i dati allegati alle App (ad esempio, fuori da SQL) e quindi richiedere dimensioni di file ridotte e velocità.

Questo articolo collegato fornisce benchmark e una buona panoramica. Ho citato alcuni punti interessanti di seguito.

https://ursalabs.org/blog/2019-10-columnar-perf/

Dimensione del file

Cioè, il file Parquet è grande la metà del CSV compresso con zip. Uno dei motivi per cui il file Parquet è così piccolo è dovuto alla codifica del dizionario (chiamata anche "compressione del dizionario"). La compressione del dizionario può produrre una compressione sostanzialmente migliore rispetto all'utilizzo di un compressore di byte per scopi generici come LZ4 o ZSTD (che sono utilizzati nel formato FST). Parquet è stato progettato per produrre file molto piccoli e veloci da leggere.

Velocità di lettura

Quando si controlla per tipo di output (ad esempio confrontando tutti gli output di data.frame tra R) vediamo che le prestazioni di Parquet, Feather e FST rientrano in un margine relativamente piccolo l'una dall'altra. Lo stesso vale per gli output pandas.DataFrame. data.table :: fread è straordinariamente competitivo con le dimensioni del file da 1,5 GB ma è in ritardo rispetto agli altri sul CSV da 2,5 GB.


Test indipendente

Ho eseguito alcuni benchmark indipendenti su un set di dati simulato di 1.000.000 di righe. Fondamentalmente ho mescolato un sacco di cose in giro per tentare di sfidare la compressione. Inoltre ho aggiunto un breve campo di testo di parole casuali e due fattori simulati.

Dati

library(dplyr)
library(tibble)
library(OpenRepGrid)

n <- 1000000

set.seed(1234)
some_levels1 <- sapply(1:10, function(x) paste(LETTERS[sample(1:26, size = sample(3:8, 1), replace = TRUE)], collapse = ""))
some_levels2 <- sapply(1:65, function(x) paste(LETTERS[sample(1:26, size = sample(5:16, 1), replace = TRUE)], collapse = ""))


test_data <- mtcars %>%
  rownames_to_column() %>%
  sample_n(n, replace = TRUE) %>%
  mutate_all(~ sample(., length(.))) %>%
  mutate(factor1 = sample(some_levels1, n, replace = TRUE),
         factor2 = sample(some_levels2, n, replace = TRUE),
         text = randomSentences(n, sample(3:8, n, replace = TRUE))
         )

Leggere e scrivere

Scrivere i dati è facile.

library(arrow)

write_parquet(test_data , "test_data.parquet")

# you can also mess with the compression
write_parquet(test_data, "test_data2.parquet", compress = "gzip", compression_level = 9)

Anche leggere i dati è facile.

read_parquet("test_data.parquet")

# this option will result in lightning fast reads, but in a different format.
read_parquet("test_data2.parquet", as_data_frame = FALSE)

Ho testato la lettura di questi dati rispetto ad alcune delle opzioni concorrenti e ho ottenuto risultati leggermente diversi rispetto all'articolo sopra, che è previsto.

Analisi comparativa

Questo file non è grande come l'articolo di riferimento, quindi forse questa è la differenza.

test

  • rds : test_data.rds (20.3 MB)
  • parquet2_native: (14.9 MB con compressione maggiore e as_data_frame = FALSE)
  • parquet2: test_data2.parquet (14.9 MB con compressione maggiore)
  • parquet: test_data.parquet (40.7 MB)
  • fst2: test_data2.fst (27.9 MB con compressione più alta)
  • prima: test_data.fst (76,8 MB)
  • fread2: test_data.csv.gz (23.6MB)
  • fread: test_data.csv (98.7MB)
  • feather_arrow: test_data.feather (157.2 MB letto con arrow)
  • piuma: test_data.feather (157.2 MB letto con feather)

osservazioni

Per questo particolare file, freadè in realtà molto veloce. Mi piace la piccola dimensione del file dal parquet2test altamente compresso . Potrei investire il tempo di lavorare con il formato di dati nativo piuttosto che adata.frame se avessi davvero bisogno di accelerare.

Ecco fstanche un'ottima scelta. Vorrei utilizzare il fstformato altamente compresso o altamente compresso a parquetseconda se avessi bisogno di compromettere la velocità o la dimensione del file.


0

Invece della convenzionale read.table sento che la fread è una funzione più veloce. Specificare attributi aggiuntivi come selezionare solo le colonne richieste, specificare colonne e stringhe come fattori ridurrà il tempo impiegato per importare il file.

data_frame <- fread("filename.csv",sep=",",header=FALSE,stringsAsFactors=FALSE,select=c(1,4,5,6,7),colClasses=c("as.numeric","as.character","as.numeric","as.Date","as.Factor"))

0

Ho provato tutto sopra e [readr] [1] ha fatto il miglior lavoro. Ho solo 8 GB di RAM

Loop per 20 file, 5 GB ciascuno, 7 colonne:

read_fwf(arquivos[i],col_types = "ccccccc",fwf_cols(cnpj = c(4,17), nome = c(19,168), cpf = c(169,183), fantasia = c(169,223), sit.cadastral = c(224,225), dt.sitcadastral = c(226,233), cnae = c(376,382)))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.