Быстрый способ чтения большого плоского файла в r как.numeric

У меня есть большой (450 МБ / 250 миллионов строк) плоский файл 1 и 0, который выглядит следующим образом...

    1
    0
    0
    1
    0
    1
    0
    etc...

Я использую следующий метод, чтобы прочитать его в R...

dat <- as.numeric(readLines("my_large_file"))

Я получаю желаемую структуру данных, но это занимает много времени. Есть предложения по более быстрому способу достижения того же результата?

NB. Порядок 1 и 0 важен для сохранения. Я хотел бы рассмотреть варианты в любом питоне командной строки Unix, но окончательная структура данных требуется в R для построения графика.

2 ответа

Решение

Вы могли бы сделать лучше с scan для числовых файлов, где вы просто хотите вернуть вектор.

scan("my_large_file", what = integer())

what Аргумент ускорит чтение вашего файла еще больше (в отличие от пропуска), поскольку вы фактически говорите R, что он будет читать целочисленные значения. scan также имеет много других аргументов, которые пригодятся с большими числовыми файлами (например, skip, nlines, так далее.)

Кроме того, как упомянуто @baptiste в комментариях,

library(data.table)
fread("my_large_file")

дует оба readLines а также scan прочь (на моей машине).

ПРИМЕЧАНИЕ: возможно, опечатка, но в вашем оригинальном посте, я думаю, readlines должно быть readLines

Сроки сравнивают пару вариантов. Сначала немного данных.

set.seed(21)
x <- sample.int(2, 25e6, TRUE) - 1L
writeLines(as.character(x),"data")

Теперь несколько тестов (каждый запускается из нового сеанса R, чтобы избежать кэширования файла).

> system.time(r <- as.numeric(readLines("data")))
   user  system elapsed 
  5.235   0.447   5.681 
> system.time(r <- scan("data",what=numeric()))
Read 25000000 items
   user  system elapsed 
  4.199   0.286   4.483 
> system.time(r <- scan("data",what=integer()))
Read 25000000 items
   user  system elapsed 
  3.134   0.081   3.214
> require(data.table)
> system.time(r <- fread("data")$V1)
   user  system elapsed 
  0.412   0.026   0.439 

И проверка:

> num <- as.numeric(readLines("data"))
> int <- as.integer(readLines("data"))
> sn <- scan("data",what=numeric())
Read 25000000 items
> si <- scan("data",what=integer())
Read 25000000 items
> dti <- fread("data")$V1
> identical(num,sn)
[1] TRUE
> identical(int,si)
[1] TRUE
> identical(int,dti)
[1] TRUE
Другие вопросы по тегам