Обрезка огромного файла CSV (на 3,5 ГБ) для чтения в R

Таким образом, у меня есть файл данных (разделенная точка с запятой), который имеет много детали и неполных строк (ведущий Доступ и SQL для дросселирования). Это - набор данных уровня графства, в который врываются сегменты, подсегменты и sub-sub-segments (для в общей сложности ~200 факторов) в течение 40 лет. Короче говоря, это огромно, и это не собирается вписываться в память, если я пытаюсь просто считать его.

Таким образом, мой вопрос - это, учитывая, что я хочу все округа, но только год (и просто высший уровень сегмента... ведущего приблизительно к 100 000 строк в конце), каков был бы лучший способ пойти о получении этой свертки в R?

В настоящее время я пытаюсь прервать несоответствующие годы с Python, обходя предел размера файла путем чтения и работы на одну строку за один раз, но я предпочел бы решение R-only (пакеты CRAN хорошо). Существует ли похожий способ считать в файлах часть за один раз в R?

Любые идеи значительно ценились бы.

Обновление:

  • Ограничения
    • Потребности использовать мою машину, таким образом, экземпляры № EC2
    • Максимально R-only. Скорость и ресурсы не являются проблемами в этом случае..., если моя машина не взрывается...
    • Как Вы видите ниже, данные содержат смешанные типы, на которые я должен воздействовать позже
  • Данные
    • Данные составляют 3.5 ГБ приблизительно с 8,5 миллионами строк и 17 столбцов
    • Пара тысячи строк (~2k) уродлива только с одним столбцом вместо 17
      • Они совершенно неважны и могут быть отброшены
    • Мне только нужны ~100 000 строк из этого файла (См. ниже),

Пример данных:

County; State; Year; Quarter; Segment; Sub-Segment; Sub-Sub-Segment; GDP; ...
Ada County;NC;2009;4;FIRE;Financial;Banks;80.1; ...
Ada County;NC;2010;1;FIRE;Financial;Banks;82.5; ...
NC  [Malformed row]
[8.5 Mill rows]

Я хочу прервать некоторые столбцы и выбрать два из 40 доступных лет (2009-2010 с 1980-2020), так, чтобы данные могли вписаться в R:

County; State; Year; Quarter; Segment; GDP; ...
Ada County;NC;2009;4;FIRE;80.1; ...
Ada County;NC;2010;1;FIRE;82.5; ...
[~200,000 rows]

Результаты:

После переделывания всех предложений сделал, я решил, что readLines, предложенный JD и Marek, будет работать лучше всего. Я дал Marek проверку, потому что он дал демонстрационную реализацию.

Я воспроизвел немного адаптированную версию реализации Marek для моего окончательного ответа здесь, с помощью strsplit и кошки для хранения только столбцов, которые я хочу.

Нужно также отметить, что это НАМНОГО менее эффективно, чем Python... как в, Python чавкает через файл на 3.5 ГБ через 5 минут, в то время как R берет приблизительно 60..., но если все, что Вы имеете, является R затем, это - билет.

## Open a connection separately to hold the cursor position
file.in <- file('bad_data.txt', 'rt')
file.out <- file('chopped_data.txt', 'wt')
line <- readLines(file.in, n=1)
line.split <- strsplit(line, ';')
# Stitching together only the columns we want
cat(line.split[[1]][1:5], line.split[[1]][8], sep = ';', file = file.out, fill = TRUE)
## Use a loop to read in the rest of the lines
line <- readLines(file.in, n=1)
while (length(line)) {
  line.split <- strsplit(line, ';')
  if (length(line.split[[1]]) > 1) {
    if (line.split[[1]][3] == '2009') {
        cat(line.split[[1]][1:5], line.split[[1]][8], sep = ';', file = file.out, fill = TRUE)
    }
  }
  line<- readLines(file.in, n=1)
}
close(file.in)
close(file.out)

Сбои подходом:

  • sqldf
    • Это определенно, что я буду использовать для этого типа проблемы в будущем, если данные будут правильно построены. Однако, если это не, затем дроссели SQLite.
  • MapReduce
    • Честно говоря, документы запугали меня на этом немного, таким образом, я не нашел время для попытки его. Было похоже, что это потребовало объекту быть в памяти также, которая победила бы точку, если бы это имело место.
  • bigmemory
    • Этот подход чисто связался с данными, но это может только обработать один тип за один раз. В результате все мои символьные векторы отбросили при помещении в big.table. Если бы я должен разработать большие наборы данных для будущего, хотя, я рассмотрел бы только числа использования только для поддержания этой опции.
  • сканирование
    • Сканирование, казалось, имело подобные проблемы типа как большую память, но со всей механикой readLines. Короче говоря, это просто не отвечало всем требованиям на этот раз.
86
задан xiaodai 13 November 2014 в 00:43
поделиться

8 ответов

Моя попытка с readLines. Этот кусок кода создает csv с выбранными годами.

file_in <- file("in.csv","r")
file_out <- file("out.csv","a")
x <- readLines(file_in, n=1)
writeLines(x, file_out) # copy headers

B <- 300000 # depends how large is one pack
while(length(x)) {
    ind <- grep("^[^;]*;[^;]*; 20(09|10)", x)
    if (length(ind)) writeLines(x[ind], file_out)
    x <- readLines(file_in, n=B)
}
close(file_in)
close(file_out)
38
ответ дан 24 November 2019 в 08:07
поделиться

Вы можете импортировать данные в базу данных SQLite , а затем использовать RSQLite для выбора подмножеств.

5
ответ дан 24 November 2019 в 08:07
поделиться

Вы изучили bigmemory ? Посмотрите это и this .

4
ответ дан 24 November 2019 в 08:07
поделиться

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

3
ответ дан 24 November 2019 в 08:07
поделиться

Возможно, вы сможете перейти на MySQL или PostgreSQL, чтобы избежать ограничений MS Access.

Довольно просто подключить R к этим системам с помощью коннектора базы данных на основе DBI (доступен в CRAN).

3
ответ дан 24 November 2019 в 08:07
поделиться

Я бы пошел за БД, а затем сделал несколько запросов, чтобы извлечь нужные вам образцы через DBI

Пожалуйста, избегайте импорта 3 , CSV-файл размером 5 ГБ в SQLite. Или, по крайней мере, дважды проверьте, что ваша ОГРОМНАЯ база данных соответствует ограничениям SQLite, http://www.sqlite.org/limits.html

У вас чертовски большая база данных. Я бы выбрал MySQL, если вам нужна скорость. Но будьте готовы ждать много часов, пока завершится импорт. Если у вас нет нестандартного оборудования или вы пишете из будущего ...

Amazon EC2 может быть хорошим решением также для создания экземпляра сервера с R и MySQL.

мои два скромных гроша стоят.

-3
ответ дан 24 November 2019 в 08:07
поделиться

Есть ли аналогичный способ чтения файлов по частям в R?

Да. Функция readChar () будет читать блок символов, не предполагая, что они оканчиваются нулем. Если вы хотите читать данные построчно, вы можете использовать readLines () . Если вы читаете блок или строку, выполняете операцию, а затем записываете данные, вы можете избежать проблемы с памятью. Хотя, если вы хотите запустить большой экземпляр памяти на Amazon EC2, вы можете получить до 64 ГБ ОЗУ. Это должно содержать ваш файл и много места для манипулирования данными.

Если вам нужно больше скорости, то рекомендация Шейна использовать Map Reduce очень хорошая. Однако, если вы выберете путь использования большого экземпляра памяти на EC2, вам следует взглянуть на многоядерный пакет для использования всех ядер на машине.

Если вы обнаружите, что хотите прочитать много гигабайт данных с разделителями в R, вам следует хотя бы изучить пакет sqldf, который позволяет импортировать непосредственно в sqldf из R, а затем работать с данными из R. Я нашел sqldf чтобы быть одним из самых быстрых способов импорта гигабайт данных в R, как упоминалось в в предыдущем вопросе .

10
ответ дан 24 November 2019 в 08:07
поделиться

Я не эксперт в этом, но вы можете попробовать MapReduce , что в основном означало бы использование подхода «разделяй и властвуй». У R есть несколько вариантов для этого, в том числе:

  1. mapReduce (чистый R)
  2. RHIPE (который использует Hadoop ); см. пример 6.2.2 в документации для примера разделения файлов

В качестве альтернативы R предоставляет несколько пакетов для работы с большими данными, которые выходят за пределы памяти (на диск). Вероятно, вы могли бы загрузить весь набор данных в объект bigmemory и полностью выполнить сокращение в R. См. http://www.bigmemory.org/ для набора инструментов для обработки этого .

10
ответ дан 24 November 2019 в 08:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: