R-советы: Экономим время и место на диске путем сжатия файла данных
Апр 04
Новости R, RTips, полезные советы, работа с данными No Comments
Начинания с R 2.10 можно читать данные прямо из текстового файла, сжатого с помощью GZIP или других программ для архивации файлов. Сжатие большого файла данных, безусловно, может сэкономить дисковое пространство: для файла, содержащего в основном цифры, 50% + уменьшение размера файла является типичным. Но не приведет ли экономия пространства к тому, что придется платить в скорости, когда дело дойдет до чтения файла с данными для анализа? Давайте попробуем это проверить.
Во-первых, сгенерируем матрицу размером 10 млн. строк и 1000 столбцов, заполненную случайными числами, и сохраним ее в отдельный файл:
#генерируем данные
x <- matrix(rnorm(1e7), ncol=1000)
#записываем в файл
write.table(x, file=»bigdata.txt», sep=»,», row.names=FALSE, col.names=FALSE)
Во-вторых, сделаем сжатие копии нашего файла с помощью Gzip, чтобы сохранить несжатую версию файла для сравнения:
#делаем копию исходного файла, чтобы потом его сжать
system(«cp bigdata.txt bigdata-compressed.txt»)
#сжимаем файл
system(«gzip bigdata-compressed.txt»)
Проверим, какого размера получились исходный и сжатый файлы с данными:
compr <- file.info(«bigdata-compressed.txt.gz»)$size
big <- file.info(«bigdata.txt»)$size
print(c(big, compr))
print(1-compr/big)
> print(c(big, compr)) [1] 181596432 83666283 > print(1-compr/big) [1] 0.5392735
Как мы видим, исходный файл 173Мб, а сжатый 79Мб, что дает нам экономию места в 55%. Теперь мы готовы провести наш тест: какой файл быстрее получится прочитать в R?
> system.time(read.table("bigdata.txt", sep=",")) пользователь система прошло 292.880 2.404 432.667 > system.time(read.table("bigdata-compressed.txt.gz", sep=",")) пользователь система прошло 188.616 1.592 240.393
Результаты показали, что сжатый файл считывается быстрее примерно в 2 раза, несмотря на то, что предварительно он должет быть распакован перед чтением. Таким образом, мы сэкономили не только место, но и время. Представьте, что вы работаете с несколькими большими данными, проводите анализ, сохраняете результаты, то такой прирост в скорости будет очень заметным.
Кстати, вместо функции read.table() можно использовать более низкоуровневую и быструю функцию scan(). Здесь результаты не столь впечатляющие:
> system.time(scan("bigdata-compressed.txt.gz", sep=",", what=rep(0,1000))) Read 10000000 items пользователь система прошло 30.072 0.324 67.200 > system.time(scan("bigdata.txt", sep=",", what=rep(0,1000))) Read 10000000 items пользователь система прошло 28.476 0.492 63.743
По мотивам: http://blog.revolutionanalytics.com/2009/12/r-tip-save-time-and-space-by-compressing-data-files.html