Я должен прочитать большой CSV-файл (5,4 ГБ с 7 млн строк и 205 столбцов) в R. Я успешно прочитал его, используя data.table::fread(). Но я хочу знать, можно ли прочитать это, используя базовый read.csv()?
Я пытался просто использовать грубую силу, но моя 16 ГБ ОЗУ не может этого выдержать. Затем я попытался использовать стратегию "разделяй и властвуй" (дробление), как показано ниже, но это все равно не сработало. Как мне это сделать?
dt1 <- read.csv('./ss13hus.csv', header = FALSE, nrows = 721900, skip =1)
print(paste(1, 'th chunk completed'))
system.time(
for (i in (1:9)){
tmp = read.csv('./ss13hus.csv', header = FALSE, nrows = 721900, skip = i * 721900 + 1)
dt1 <- rbind(dt1, tmp)
print(paste(i + 1, 'th chunk completed'))
}
)
Также я хочу знать, как работает fread(), который может считывать все данные сразу и очень эффективно, независимо от памяти или времени?
Ответ 1 · рейтинг 4 · smci
Ваша проблема не fread(), это раздувание памяти, вызванное тем, что не определены colClasses для всех ваших (205) столбцов. Но имейте в виду, что попытка прочитать все 5,4 ГБ в 16 ГБ ОЗУ, в первую очередь, напрягает, вы почти наверняка не сможете хранить весь этот набор данных в памяти; и даже если бы вы могли, вы будете сбрасывать память всякий раз, когда пытаетесь ее обработать. Таким образом, ваш подход не сработает, вам нужно серьезно решить, с каким подмножеством вы можете работать, какие поля вам абсолютно необходимы для начала работы:
Определите colClasses для ваших 205 столбцов: "integer" для целочисленных столбцов, "numeric" для двойных столбцов, "logical" для логических столбцов, "factor" для столбцов-факторов. В противном случае вещи хранятся очень неэффективно (например, миллионы строк очень расточительны), и результат может легко быть в 5-100 раз больше, чем необработанный файл.
Если вы не можете уместить все 7 млн строк x 205 столбцов (что почти наверняка не удастся), то вам придется агрессивно сократить объем памяти, выполнив некоторые или все из следующих действий:
- read in and process chunks (of rows) (use
skip, nrows arguments, and search SO for questions on fread in chunks)
- отфильтровать все ненужные строки (например, вы можете выполнить некоторую грубую обработку, чтобы сформировать индекс строки из подмножества строк, которые вам нужны, и позже импортировать этот гораздо меньший набор)
- удалить все ненужные столбцы (используйте аргументы fread
select/drop (укажите векторы имен столбцов, которые нужно сохранить или удалить).
Убедитесь, что опция stringsAsFactors=FALSE - это заведомо плохой вариант по умолчанию в R, который вызывает бесконечные проблемы с памятью.
- Поля даты/даты-времени в настоящее время читаются как символы (что плохо для использования памяти, миллионы уникальных строк). Либо полностью удалите столбцы даты для начала, либо прочитайте данные по частям и преобразуйте их с помощью пакета
fasttime или стандартных базовых функций.
- Посмотрите на аргументы для обработки NA. На данный момент вы можете отказаться от столбцов с большим количеством NA или беспорядочных необработанных строковых полей.
См. ?fread и data.table документ для синтаксис вышеперечисленного. Если вы столкнулись с конкретной ошибкой, опубликуйте фрагмент, скажем, 2 строки данных (head(data)), ваш код и ошибку.