Подтвердить что ты не робот

R, читающий огромный csv

У меня огромный файл csv. Его размер составляет около 9 ГБ. У меня 16 гб барана. Я следил за советами на странице и реализовал их ниже.

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 

Тем не менее, я получаю сообщение об ошибке и предупреждениях ниже. Как читать файл 9 gb в R? У меня R 64 бит 3.3.1, и я запускаю команду ниже в rstudio 0.99.903. У меня есть сервер windows 2012 r2, 64-битный os.

> 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

Моя первая попытка основана на предложенном ответе

> 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

моя вторая попытка, основанная на предлагаемом ответе, ниже

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)

Как я могу прочитать этот файл в одном объекте, чтобы я мог анализировать все данные за один раз

------------------ обновление 3

Мы купили дорогую машину. Он имеет 10 ядер и 256 ГБ оперативной памяти. Это не самое эффективное решение, но оно работает как минимум в ближайшем будущем. Я посмотрел ниже ответы, и я не думаю, что они решают мою проблему:( Я ценю эти ответы. Я хочу выполнить анализ корзины на рынке, и я не думаю, что нет другого пути, кроме сохранения моих данных в ОЗУ.

4b9b3361

Ответ 1

Убедитесь, что вы используете 64-битную R, а не только 64-битную Windows, чтобы увеличить объем памяти RAM до 16 ГБ.

Кроме того, вы можете прочитать в файле куски:

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

Вы можете использовать data.table для более эффективного чтения и управления большими файлами:

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

При необходимости вы можете использовать память памяти с помощью ff:

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

Ответ 2

Возможно, вы захотите рассмотреть возможность использования некоторой обработки на диске и не иметь весь этот объект в памяти R. Одним из вариантов было бы сохранение данных в соответствующей базе данных, а затем доступ к R. dplyr способен иметь дело с удаленным исходным кодом (он фактически записывает операторы SQL для запроса базы данных). Я только что проверил это с небольшим примером (всего 17 500 строк), но, надеюсь, он будет соответствовать вашим требованиям.

Установка SQLite

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

Введите данные в новую базу данных SQLite

  • Сохраните следующее в новом файле с именем import.sql

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

Да, вам нужно указать имена столбцов самостоятельно (я считаю), но вы можете указать их типы здесь, если хотите. Это не будет работать, если у вас есть запятые в любом месте ваших имен/данных, конечно.

  • Импортировать данные в базу данных SQLite через командную строку

sqlite3.exe BIGDATA.sqlite3 < import.sql

Точка dplyr в базу данных SQLite

Поскольку мы используем SQLite, все зависимости обрабатываются dplyr уже.

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

Проведите поисковый анализ

dplyr будет писать команды SQLite, необходимые для запроса этого источника данных. В противном случае он будет вести себя как локальная таблица. Большим исключением будет то, что вы не можете запросить количество строк.

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

Ответ 3

Это может быть невозможно на вашем компьютере. В некоторых случаях data.table занимает больше места, чем его аналог .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

Два OOM больше:

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

Есть естественные накладные расходы для хранения объекта в R. На основе этих чисел при чтении файлов примерно 1,33 коэффициент, однако это зависит от данных. Например, используя

  • x = sample(1:10000000,10000000,replace = T) дает коэффициент примерно 2x (R: csv).

  • x = sample(c("foofoofoo","barbarbar"),10000000,replace = T) дает коэффициент 0,5x (R: csv).

Основываясь на максимальном размере, ваш 9-гигабайтный файл может использовать 18 ГБ памяти для хранения в R, если не больше. Исходя из вашего сообщения об ошибке, гораздо более вероятно, что вы нажимаете жесткие ограничения памяти и проблемы с распределением. Поэтому просто чтение вашего файла в патронах и консолидация не сработают - вам также понадобится разделить ваш анализ + рабочий процесс. Другой альтернативой является использование встроенного инструмента памяти, такого как SQL.

Ответ 4

Это была бы ужасная практика, но в зависимости от того, как вам нужно обрабатывать эти данные, это не должно быть слишком плохо. Вы можете изменить максимальную память, которую R разрешено использовать, вызывая memory.limit(new) где new целое число с R new memory.limit в MB. Что произойдет, когда вы столкнетесь с аппаратным ограничением, окна запустит пейджинговую память на жесткий диск (не самое худшее в мире, но это сильно замедлит вашу обработку).

Если вы используете это на серверной версии пейджинга Windows, возможно, (скорее всего) будет работать иначе, чем с обычной Windows 10. Я считаю, что она должна быть быстрее, поскольку ОС сервера следует оптимизировать для этого.

Попробуйте начать с чего-то в строках 32 ГБ (или memory.limit(memory.limit()*2)), и если он выйдет намного больше, я бы сказал, что программа будет слишком медленной один раз он загружается в память. В этот момент я бы порекомендовал купить еще немного ОЗУ или найти способ обработки по частям.

Ответ 5

Вы можете попробовать разделить обработку по таблице. Вместо того, чтобы работать во всем, поставьте всю операцию в цикле for и сделайте это 16, 32, 64 или сколько бы раз вам не понадобилось. Любые значения, необходимые для последующего вычисления, могут быть сохранены. Это не так быстро, как другие сообщения, но он обязательно вернется.

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

Надеюсь, что это поможет.