it-swarm.com.de

R liest eine riesige csv

Ich habe eine riesige CSV-Datei. Seine Größe beträgt ca. 9 gb. Ich habe 16 GB RAM. Ich folgte den Ratschlägen von der Seite und setzte sie unten um.

If you get the error that R cannot allocate a vector of length x, close out of R and add the following line to the ``Target'' field: 
--max-vsize=500M 

Dennoch erhalte ich den Fehler und die Warnungen unten. Wie soll ich die Datei mit 9 GB in mein R lesen? Ich habe R 64 Bit 3.3.1 und ich laufe unter Befehl im rstudio 0.99.903. Ich habe Windows Server 2012 R2 Standard, 64-Bit-Betriebssystem.

> memory.limit()
[1] 16383
> answer=read.csv("C:/Users/a-vs/results_20160291.csv")
Error: cannot allocate vector of size 500.0 Mb
In addition: There were 12 warnings (use warnings() to see them)
> warnings()
Warning messages:
1: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
2: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
3: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
4: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
5: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
6: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
7: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
8: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
9: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
10: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
11: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
12: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)

------------------- Update1

Mein erster Versuch basiert auf der vorgeschlagenen Antwort

> thefile=fread("C:/Users/a-vs/results_20160291.csv", header = T)
Read 44099243 rows and 36 (of 36) columns from 9.399 GB file in 00:13:34
Warning messages:
1: In fread("C:/Users/a-vsingh/results_tendo_20160201_20160215.csv",  :
  Reached total allocation of 16383Mb: see help(memory.size)
2: In fread("C:/Users/a-vsingh/results_tendo_20160201_20160215.csv",  :
  Reached total allocation of 16383Mb: see help(memory.size)

------------------- Update2

mein 2. Versuch basierend auf der vorgeschlagenen Antwort ist wie folgt

thefile2 <- read.csv.ffdf(file="C:/Users/a-vs/results_20160291.csv", header=TRUE, VERBOSE=TRUE, 
+                    first.rows=-1, next.rows=50000, colClasses=NA)
read.table.ffdf 1..
Error: cannot allocate vector of size 125.0 Mb
In addition: There were 14 warnings (use warnings() to see them)

Wie könnte ich diese Datei in ein einzelnes Objekt einlesen, damit ich die gesamten Daten auf einmal analysieren kann?

------------------ Update 3

Wir haben eine teure Maschine gekauft. Es hat 10 Kerne und 256 GB RAM. Das ist nicht die effizienteste Lösung, funktioniert aber zumindest in naher Zukunft. Ich habe mir die folgenden Antworten angesehen und glaube nicht, dass sie mein Problem lösen :( Ich schätze diese Antworten. Ich möchte die Warenkorbanalyse durchführen und glaube nicht, dass es keinen anderen Weg gibt, als meine Daten im RAM zu behalten

15
user2543622

Stellen Sie sicher, dass Sie 64-Bit-R und nicht nur 64-Bit-Windows verwenden, damit Sie die RAM -Zuweisung auf alle 16 GB erhöhen können.

Außerdem können Sie die Datei in Blöcken einlesen:

file_in    <- file("in.csv","r")
chunk_size <- 100000 # choose the best size for you
x          <- readLines(file_in, n=chunk_size)

Mit data.table können Sie große Dateien effizienter lesen und bearbeiten:

require(data.table)
fread("in.csv", header = T)

Bei Bedarf können Sie den Speicher mit ff nutzen:

library("ff")
x <- read.csv.ffdf(file="file.csv", header=TRUE, VERBOSE=TRUE, 
                   first.rows=10000, next.rows=50000, colClasses=NA)
14
Hack-R

Möglicherweise möchten Sie einen Teil der Festplattenverarbeitung nutzen und nicht das gesamte Objekt in Rs Speicher haben. Eine Möglichkeit wäre, die Daten in einer richtigen Datenbank zu speichern und dann Zugriff darauf zu haben. dplyr kann mit einer entfernten Quelle umgehen (es schreibt tatsächlich die SQL-Anweisungen, um die Datenbank abzufragen). Ich habe dies gerade mit einem kleinen Beispiel (nur 17.500 Zeilen) getestet, aber hoffentlich wird es Ihren Anforderungen gerecht.

Installieren Sie SQLite

https://www.sqlite.org/download.html

Geben Sie die Daten in eine neue SQLite-Datenbank ein

  • Speichern Sie Folgendes in einer neuen Datei mit dem Namen import.sql

CREATE TABLE tableName (COL1, COL2, COL3, COL4); .separator , .import YOURDATA.csv tableName

Ja, Sie müssen die Spaltennamen selbst angeben (glaube ich), aber Sie können auch deren Typ hier angeben, wenn Sie möchten. Dies funktioniert natürlich nicht, wenn Ihre Namen/Daten Kommas enthalten.

  • Importieren Sie die Daten über die Befehlszeile in die SQLite-Datenbank

sqlite3.exe BIGDATA.sqlite3 < import.sql

Zeigen Sie mit dplyr auf die SQLite-Datenbank

Da wir SQLite verwenden, werden alle Abhängigkeiten bereits von dplyr behandelt.

library(dplyr) my_db <- src_sqlite("/PATH/TO/YOUR/DB/BIGDATA.sqlite3", create = FALSE) my_tbl <- tbl(my_db, "tableName")

Machen Sie Ihre Erkundungsanalyse

dplyr schreibt die SQLite-Befehle, die zum Abfragen dieser Datenquelle erforderlich sind. Ansonsten verhält es sich wie eine lokale Tabelle. Die große Ausnahme wird sein, dass Sie die Anzahl der Zeilen nicht abfragen können.

my_tbl %>% group_by(COL2) %>% summarise(meanVal = mean(COL3))

#>  Source:   query [?? x 2]
#>  Database: sqlite 3.8.6 [/PATH/TO/YOUR/DB/BIGDATA.sqlite3]
#>  
#>         COL2    meanVal
#>        <chr>      <dbl>
#>  1      1979   15.26476
#>  2      1980   16.09677
#>  3      1981   15.83936
#>  4      1982   14.47380
#>  5      1983   15.36479
9

Dies ist auf Ihrem Computer möglicherweise nicht möglich. In bestimmten Fällen nimmt data.table mehr Platz ein als sein Gegenstück .csv.

DT <- data.table(x = sample(1:2,10000000,replace = T))
write.csv(DT, "test.csv") #29 MB file
DT <- fread("test.csv", row.names = F)   
object.size(DT)
> 40001072 bytes #40 MB

Zwei OOM größer:

DT <- data.table(x = sample(1:2,1000000000,replace = T))
write.csv(DT, "test.csv") #2.92 GB file
DT <- fread("test.csv", row.names = F)   
object.size(DT)
> 4000001072 bytes #4.00 GB

Das Speichern eines Objekts in R ist natürlich mit einem Mehraufwand verbunden. Ausgehend von diesen Zahlen ergibt sich beim Lesen von Dateien ein Faktor von ungefähr 1,33. Dies hängt jedoch von den Daten ab. Zum Beispiel mit

  • x = sample(1:10000000,10000000,replace = T) gibt einen Faktor von ungefähr 2x (R: csv) an.

  • x = sample(c("foofoofoo","barbarbar"),10000000,replace = T) ergibt einen Faktor von 0,5x (R: csv).

Basierend auf dem Maximalwert würde Ihre 9-GB-Datei möglicherweise 18 GB Speicherplatz in R benötigen, wenn nicht mehr. Anhand Ihrer Fehlermeldung ist es weitaus wahrscheinlicher, dass Sie aufgrund eines Zuordnungsproblems auf Speicherbeschränkungen stoßen. Daher würde es nicht funktionieren, nur Ihre Datei in Chucks zu lesen und zu konsolidieren - Sie müssten auch Ihre Analyse und Ihren Workflow partitionieren. Eine andere Alternative ist die Verwendung eines In-Memory-Tools wie SQL.

5
Chris

Dies wäre eine schreckliche Übung, aber je nachdem, wie Sie diese Daten verarbeiten müssen, sollte sie nicht zu schlecht sein. Sie können Ihren maximalen Speicher ändern, den R verwenden darf, indem Sie memory.limit(new) aufrufen, wobei new eine Ganzzahl mit Rs neuem memory.limit inMBist. Was passiert, ist, wenn Sie die Hardware-Einschränkung treffen, Windows beginnt, Speicher auf der Festplatte auszulagern (nicht das Schlimmste auf der Welt, aber es wird Ihre Verarbeitung stark verlangsamen).

Wenn Sie dies auf einer Serverversion von Windows Paging ausführen, funktioniert Paging möglicherweise (wahrscheinlich) anders als unter Windows 10. Ich glaube, es sollte schneller sein, da das Serverbetriebssystem für dieses Zeug optimiert werden sollte.

Beginnen Sie mit etwas in der Größenordnung von 32 GB (oder memory.limit(memory.limit()*2)), und wenn es VIEL größer ausfällt, würde ich sagen, dass das Programm nach dem Laden in den Speicher zu langsam wird. An diesem Punkt würde ich empfehlen, etwas mehr RAM zu kaufen oder einen Weg zu finden, um Teile zu verarbeiten.

1
Adam

Sie können versuchen, Ihre Verarbeitung über die Tabelle aufzuteilen. Anstatt die ganze Sache zu bearbeiten, platzieren Sie die gesamte Operation in einer for-Schleife und führen Sie sie 16, 32, 64 oder so oft aus, wie Sie es benötigen. Alle Werte, die Sie für eine spätere Berechnung benötigen, können gespeichert werden. Dies ist nicht so schnell wie andere Beiträge, aber es wird definitiv zurückkehren.

x = number_of_rows_in_file / CHUNK_SIZE
for (i in c(from = 1, to = x, by = 1)) {
    read.csv(con, nrows=CHUNK_SIZE,...)
}

Hoffentlich hilft das.

0
Woody1193