У меня есть очень большие таблицы (30 миллионов строк), которые я хотел бы загрузить в виде фреймов данных в R. read.table()
Имеет много удобных функций, но, похоже, в реализации много логики, которая может замедлить работу. В моем случае, я предполагаю, что знаю типы столбцов заранее, таблица не содержит заголовков столбцов или имен строк и не имеет патологических символов, о которых мне нужно беспокоиться.
Я знаю, что чтение в таблице в виде списка scan()
может быть довольно быстрым, например:
datalist <- scan('myfile',sep='\t',list(url='',popularity=0,mintime=0,maxtime=0)))
Но некоторые из моих попыток преобразовать это в фрейм данных, кажется, снижают производительность вышеупомянутого в 6 раз:
df <- as.data.frame(scan('myfile',sep='\t',list(url='',popularity=0,mintime=0,maxtime=0))))
Есть ли лучший способ сделать это? Или, может быть, совершенно другой подход к проблеме?
feather
. Для чтения данныхfeather
гораздо быстрее, чемfread
. Например, в только что загруженном наборе данных объемом 4 ГБread_feather
скорость была примерно в 4,5 раза вышеfread
. Для сохранения данныхfwrite
все еще быстрее. blog.dominodatalab.com/the-r-data-io-shootoutfeather
быстрее для чтения, но он использует гораздо больше места для хранения.feather
это хороший вариант. Если вас интересует только возможность прочитать ваши данные в R,rds
предпочтительнее.Вот пример, который использует
fread
отdata.table
1.8.7Примеры приведены на странице справки
fread
, где приведены временные параметры на моем Windows XP Core 2 Duo E8400.стандартный read.table
оптимизированный read.table
Fread
sqldf
фф / ффдф
В итоге:
источник
fread
. Попытался прочитать его с помощью базовых функций R, и это заняло около 15 часов.readr
?fread
есть некоторые реальные конкуренты, может быть полезно добавить тесты для оптимизированногоfread
использования - указаниеcolClasses
и т. Д.Сначала я не видел этот вопрос и через несколько дней задал похожий вопрос. Я собираюсь снять свой предыдущий вопрос, но я решил добавить сюда ответ, чтобы объяснить, как я
sqldf()
это делал.Там было немного дискуссий о том, как лучше всего импортировать 2 ГБ или более текстовых данных во фрейм данных R. Вчера я написал сообщение в блоге о том,
sqldf()
как импортировать данные в SQLite в качестве промежуточной области, а затем сосать их из SQLite в R. Это очень хорошо работает для меня. Мне удалось получить 2 ГБ (3 столбца, 40 мм строки) данных за <5 минут. В отличие от этогоread.csv
команда выполнялась всю ночь и никогда не выполнялась.Вот мой тестовый код:
Настройте тестовые данные:
Я перезапустил R перед запуском следующей процедуры импорта:
Я позволил следующей строке работать всю ночь, но она так и не завершилась:
источник
Как ни странно, никто не отвечал на нижнюю часть вопроса в течение многих лет, даже если это важный вопрос -
data.frame
это просто списки с правильными атрибутами, поэтому если у вас есть большие данные, которые вы не хотите использоватьas.data.frame
или похожие для списка. Гораздо быстрее просто «превратить» список в фрейм данных на месте:Это не делает копию данных, поэтому это немедленно (в отличие от всех других методов). Предполагается, что вы уже установили
names()
в списке соответственно.[Что касается загрузки больших данных в R - лично я дам их по столбцам в двоичные файлы и использую
readBin()
- это, безусловно, самый быстрый метод (кроме mmapping), который ограничен только скоростью диска. Анализ файлов ASCII по своей сути медленен (даже в C) по сравнению с двоичными данными.]источник
tracmem
подсказывает, чтоattr<-
иclass<-
делать копии внутри.bit::setattr
илиdata.table::setattr
не будет.df=scan(...); names(df)=...; attr...; class...
- см.tracemem()
(Проверено в R 2.15.2)Раньше об этом спрашивали в R-Help , так что стоит посмотреть.
Одно из предложений заключалось в том, чтобы использовать,
readChar()
а затем выполнять строковые операции с результатомstrsplit()
иsubstr()
. Вы можете видеть, что логика readChar намного меньше, чем read.table.Я не знаю, является ли здесь проблема с памятью, но вы также можете взглянуть на пакет HadoopStreaming . При этом используется Hadoop , который представляет собой инфраструктуру MapReduce, предназначенную для работы с большими наборами данных. Для этого вы бы использовали функцию hsTableReader. Это пример (но у него есть кривая обучения для изучения Hadoop):
Основная идея здесь - разбить импорт данных на куски. Вы могли бы даже пойти так далеко, чтобы использовать одну из параллельных сред (например, Snow) и запустить импорт данных параллельно, сегментируя файл, но, скорее всего, для больших наборов данных, которые не помогут, поскольку вы столкнетесь с ограничениями памяти, именно поэтому карта-сокращение является лучшим подходом.
источник
Альтернативой является использование
vroom
пакета. Теперь на CRAN.vroom
не загружает весь файл, он индексирует, где находится каждая запись, и читается позже, когда вы его используете.См. Введение в vroom , Начало работы с vroom и тесты vroom .
Основной обзор заключается в том, что первоначальное чтение огромного файла будет намного быстрее, а последующие изменения данных могут быть немного медленнее. Таким образом, в зависимости от того, что вы используете, это может быть лучшим вариантом.
Посмотрите упрощенный пример из тестов vroom ниже, ключевые моменты, которые нужно увидеть, - это супер быстрое время чтения, но немного ускоряющие операции, такие как агрегирование и т. Д.
источник
Незначительные дополнительные моменты стоит упомянуть. Если у вас очень большой файл, вы можете на лету рассчитать количество строк (если нет заголовка), используя (где
bedGraph
имя вашего файла в вашем рабочем каталоге):Затем вы можете использовать что либо
read.csv
,read.table
...источник
Часто я думаю, что это хорошая практика - хранить большие базы данных внутри базы данных (например, Postgres). Я не использую ничего слишком большого, чем (nrow * ncol) ncell = 10M, что довольно мало; но я часто нахожу, что хочу, чтобы R создавал и содержал графики, интенсивно использующие память, только когда я выполняю запросы из нескольких баз данных. В будущем 32-ГБ ноутбуки некоторые из этих типов проблем с памятью исчезнут. Но привлекательность использования базы данных для хранения данных и последующего использования памяти R для получения результатов запроса и графиков все еще может быть полезной. Некоторые преимущества:
(1) Данные остаются загруженными в вашу базу данных. Вы просто переподключаетесь в pgadmin к нужным базам данных, когда снова включаете свой ноутбук.
(2) Это правда, что R может выполнять намного больше изящных статистических и графических операций, чем SQL. Но я думаю, что SQL лучше подходит для запросов больших объемов данных, чем R.
источник
Я очень быстро читаю данные, используя новый
arrow
пакет. Похоже, на довольно ранней стадии.В частности, я использую паркетный столбчатый формат. Это преобразует обратно в a
data.frame
в R, но вы можете получить еще более быстрое ускорение, если вы этого не сделаете. Этот формат удобен тем, что его можно использовать и в Python.Мой основной сценарий использования этого - довольно ограниченный сервер RShiny. По этим причинам я предпочитаю хранить данные, прикрепленные к приложениям (то есть вне SQL), и поэтому требую небольшой размер файла и скорость.
Эта связанная статья обеспечивает сравнительный анализ и хороший обзор. Я привел некоторые интересные моменты ниже.
https://ursalabs.org/blog/2019-10-columnar-perf/
Размер файла
Скорость чтения
Независимый тест
Я выполнил некоторые независимые тесты для имитированного набора данных из 1 000 000 строк. По сути, я перетасовал кучу вещей, пытаясь бросить вызов сжатию. Также я добавил короткое текстовое поле случайных слов и два имитируемых фактора.
Данные
Прочти и напиши
Написание данных легко.
Чтение данных также легко.
Я проверил чтение этих данных по нескольким конкурирующим вариантам и получил немного другие результаты, чем в статье выше, что ожидается.
Этот файл далеко не такой большой, как эталонная статья, так что, возможно, в этом и заключается разница.
тесты
as_data_frame = FALSE
)arrow
)feather
)наблюдения
Для этого конкретного файла,
fread
на самом деле очень быстро. Мне нравится маленький размер файла из сильно сжатогоparquet2
теста. Я могу потратить время на работу с собственным форматом данных, а неdata.frame
если мне действительно нужно ускорить работу.Здесь
fst
также отличный выбор. Я бы использовал либо сильно сжатыйfst
формат, либо сильно сжатый, вparquet
зависимости от того, нужна ли мне компромисс между скоростью или размером файла.источник
Вместо обычного read.table я чувствую, что fread - более быстрая функция. Задание дополнительных атрибутов, таких как выбор только необходимых столбцов, указание классов и строк в качестве факторов, уменьшит время, необходимое для импорта файла.
источник
Я перепробовал все выше и [readr] [1] сделал лучшую работу. У меня только 8гб оперативки
Цикл для 20 файлов, 5 ГБ каждый, 7 столбцов:
источник