Быстрое чтение очень больших таблиц как данных

Используйте функцию CLIM (эквивалентную функции CAXIS в MATLAB):

plt.pcolor(X, Y, v, cmap=cm)
plt.clim(-4,4)
plt.show()

474
задан Uwe Keim 3 June 2018 в 12:36
поделиться

4 ответа

Обновление, несколько лет спустя

Это старый ответ, и R продолжил работу. Настройка read.table для более быстрой работы имеет мало пользы. Возможны следующие варианты:

  1. Использование fread в data.table для импорта данных из файлов csv / с разделителями табуляции непосредственно в R. См. Ответ mnel .

  2. Использование read_table в readr (в CRAN с апреля 2015 г.). Это работает так же, как fread выше. readme в ссылке объясняет разницу между двумя функциями ( readr в настоящее время утверждает, что он «в 1,5-2 раза медленнее», чем data.table :: fread ) .

  3. read.csv.raw из iotools предоставляет третий вариант для быстрого чтения файлов CSV.

  4. Попытка хранить как можно больше данных в базах данных, а не в плоских файлах. (Помимо того, что это лучший постоянный носитель данных, данные передаются в R и из R в двоичном формате, что быстрее.) read.csv.sql в пакете sqldf , как описано в ответ JD Long , импортирует данные во временную базу данных SQLite, а затем считывает их в R. См. также: пакет RODBC , и обратный раздел зависит от DBI пакет страница. MonetDB.R предоставляет вам тип данных, который выдает себя за фрейм данных, но на самом деле является MonetDB под ним, повышая производительность. Импортируйте данные с помощью функции monetdb.read.csv . dplyr позволяет работать напрямую с данными, хранящимися в нескольких типах баз данных.

  5. Хранение данных в двоичных форматах также может быть полезно для повышения производительности. Используйте saveRDS / readRDS (см. Ниже), пакеты h5 или rhdf5 для формата HDF5 или write_fst / read_fst из пакета fst .


Исходный ответ

Есть несколько простых вещей, которые можно попробовать, независимо от того, используете ли вы read.table или scan.

  1. Установите nrows = количество записей в ваших данных ( nmax в сканировании ).

  2. Убедитесь, что комментарий .char = "" , чтобы отключить интерпретацию комментариев.

  3. Явно определите классы каждого столбца, используя colClasses в read.table .

  4. Настройка ] мульти. line = FALSE также может улучшить производительность при сканировании.

Если ничего из этого не работает, то используйте один из пакетов профилирования , чтобы определить, какие строки замедляют работу. Возможно, вы сможете написать урезанную версию read.table на основе результатов.

Другой альтернативой является фильтрация ваших данных перед их чтением в R.

Или, если проблема в том, что вы должны регулярно читать его, затем использовать эти методы для однократного считывания данных, затем сохранить фрейм данных как двоичный объект с помощью save saveRDS , а затем в следующий раз вы можете получить его быстрее с помощью загрузить readRDS .

406
ответ дан 22 November 2019 в 22:43
поделиться

Я считываю данные очень быстро использование нового arrow пакет. Это, кажется, находится на довольно ранней стадии.

А именно, я использую паркет колоночный формат. Это преобразовывает назад в data.frame в R, но можно получить еще более глубокие ускорения, если Вы не делаете. Этот формат удобен, поскольку он может использоваться из Python также.

Мой основной вариант использования для этого идет довольно сдержанный сервер RShiny. По этим причинам я предпочитаю сохранять данные присоединенными к Приложениям (т.е. из SQL) и поэтому требовать небольшого размера файла, а также скорости.

Эта связанная статья предоставляет сравнительное тестирование и хороший обзор. Я заключил некоторые интересные моменты в кавычки ниже.

https://ursalabs.org/blog/2019-10-columnar-perf /

Размер файла

таким образом, файл Паркета является вдвое менее большим, чем даже gzipped CSV. Одна из причин, что файл Паркета является настолько маленьким, из-за кодирования словаря (также названа “dictionary compression”). Сжатие словаря может привести к существенно лучшему сжатию, чем использование компрессора байтов общего назначения как LZ4 или ZSTD (которые используются в формате FST). Паркет был разработан для создания очень маленьких файлов, которые быстры для чтения.

Скорость Read

При управлении выходным типом (например, сравнении всего R data.frame выводы друг с другом) мы видим производительность Паркета, Растушевку, и FST находится в пределах относительно маленького поля друг друга. То же верно для панд. Выводы DataFrame. data.table:: освобожденный чрезвычайно конкурентоспособно по отношению к размеру файла на 1,5 ГБ, но изолирует другие на CSV на 2,5 ГБ.

<час>

Независимый Тест

я выполнил некоторое независимое сравнительное тестирование на моделируемом наборе данных 1 000 000 строк. В основном я переставил набор вещей вокруг, чтобы попытаться бросить вызов сжатию. Также я добавил поле краткого текста случайных слов и двух моделируемых факторов.

Данные

library(dplyr)
library(tibble)
library(OpenRepGrid)

n <- 1000000

set.seed(1234)
some_levels1 <- sapply(1:10, function(x) paste(LETTERS[sample(1:26, size = sample(3:8, 1), replace = TRUE)], collapse = ""))
some_levels2 <- sapply(1:65, function(x) paste(LETTERS[sample(1:26, size = sample(5:16, 1), replace = TRUE)], collapse = ""))


test_data <- mtcars %>%
  rownames_to_column() %>%
  sample_n(n, replace = TRUE) %>%
  mutate_all(~ sample(., length(.))) %>%
  mutate(factor1 = sample(some_levels1, n, replace = TRUE),
         factor2 = sample(some_levels2, n, replace = TRUE),
         text = randomSentences(n, sample(3:8, n, replace = TRUE))
         )

Read и Запись

Запись данных легка.

library(arrow)

write_parquet(test_data , "test_data.parquet")

# you can also mess with the compression
write_parquet(test_data, "test_data2.parquet", compress = "gzip", compression_level = 9)

Чтение данных также легко.

read_parquet("test_data.parquet")

# this option will result in lightning fast reads, but in a different format.
read_parquet("test_data2.parquet", as_data_frame = FALSE)

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

benchmarking

Этот файл нигде не является рядом столь же большим как статья сравнительного теста, настолько возможно, который различие.

Тесты

  • rds: test_data.rds (20,3 МБ)
  • parquet2_native: (14,9 МБ с более высоким сжатием и as_data_frame = FALSE)
  • parquet2: test_data2.parquet (14,9 МБ с более высоким сжатием)
  • паркет: test_data.parquet (40,7 МБ)
  • fst2: test_data2.fst (27,9 МБ с более высоким сжатием)
  • fst: test_data.fst (76,8 МБ)
  • fread2: test_data.csv.gz (23.6 МБ)
  • освобожденный: test_data.csv (98.7 МБ)
  • feather_arrow: test_data.feather (чтение на 157,2 МБ с arrow)
  • растушевка: test_data.feather (чтение на 157,2 МБ с feather)

Наблюдения

Для этого конкретного файла, fread на самом деле очень быстр. Мне нравится небольшой размер файла от очень сжатый parquet2 тест. Я могу инвестировать время для работы с собственным форматом данных, а не data.frame, если мне действительно нужна скорость.

Здесь fst также большой выбор. Я или использовал бы очень сжатый fst формат или очень сжатый parquet в зависимости от того, если бы мне была нужна скорость, или размер файла обменивают.

1
ответ дан 22 November 2019 в 22:43
поделиться

Ранее спрашивали на R-Help , так что это стоит обзор.

Было предложено использовать readChar () , а затем выполнять строковые манипуляции с результатом с помощью strsplit () и substr () . Вы можете видеть, что логика, задействованная в readChar, намного меньше, чем в read.table.

Я не знаю, является ли здесь проблема с памятью, но вы также можете взглянуть на HadoopStreaming пакет . Этот использует Hadoop , который представляет собой структуру MapReduce, предназначенную для работы с большими наборами данных. Для этого вы должны использовать функцию hsTableReader. Это пример (но для изучения Hadoop необходимо время):

str <- "key1\t3.9\nkey1\t8.9\nkey1\t1.2\nkey1\t3.9\nkey1\t8.9\nkey1\t1.2\nkey2\t9.9\nkey2\"
cat(str)
cols = list(key='',val=0)
con <- textConnection(str, open = "r")
hsTableReader(con,cols,chunkSize=6,FUN=print,ignoreKey=TRUE)
close(con)

Основная идея здесь - разбить импорт данных на части. Вы даже можете пойти дальше и использовать одну из параллельных сред (например, снег) и запустить импорт данных параллельно, сегментируя файл,

31
ответ дан 22 November 2019 в 22:43
поделиться

Я не видел этого вопрос изначально и задал аналогичный вопрос несколько дней спустя. Я собираюсь ответить на свой предыдущий вопрос, но решил добавить здесь ответ, чтобы объяснить, как я использовал sqldf () для этого.

Было небольшое обсуждение относительно наилучшего способа импорта 2 ГБ или более текстовых данных во фрейм данных R. Вчера я написал сообщение в блоге об использовании sqldf () для импорта данных в SQLite в качестве промежуточной области, а затем втягивания их из SQLite в R. Это очень хорошо работает для меня. Мне удалось получить 2 ГБ (3 столбца, строки по 40 мм) менее чем за 5 минут. Напротив, читал. Команда csv выполнялась всю ночь и так и не была завершена.

Вот мой тестовый код:

Настройте тестовые данные:

bigdf <- data.frame(dim=sample(letters, replace=T, 4e7), fact1=rnorm(4e7), fact2=rnorm(4e7, 20, 50))
write.csv(bigdf, 'bigdf.csv', quote = F)

Я перезапустил R перед выполнением следующей процедуры импорта:

library(sqldf)
f <- file("bigdf.csv")
system.time(bigdf <- sqldf("select * from f", dbname = tempfile(), file.format = list(header = T, row.names = F)))

Я позволил следующей строке работать всю ночь, но она так и не завершилась:

system.time(big.df <- read.csv('bigdf.csv'))
249
ответ дан 22 November 2019 в 22:43
поделиться
Другие вопросы по тегам:

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