Моя группа не работает с дисковыми фреймами

Я запустил группу на большом наборе данных (>20 ГБ), и, похоже, он работает не совсем правильно

Это мой код

mydf[, .(value = n_distinct(list_of_id, na.rm = T)),
                      by = .(week),
                      keep = c("list_of_id", "week")
                      ] 

Он вернул эту ошибку

Предупреждающие сообщения: 1: In serialize (data, node $ con):
'package: MLmetrics' может быть недоступен при загрузке 2: In serialize(data, node$con): 'package:MLmetrics' может быть недоступен при загрузке 3: In serialize(data, node$con): 'package:MLmetrics' может быть недоступен при загрузке 4: In serialize (data, node $ con):
'package: MLmetrics' может быть недоступен при загрузке 5: In serialize(data, node$con): 'package:MLmetrics' может быть недоступен при загрузке 6: In serialize(data, node$con): 'package:MLmetrics' может быть недоступен при загрузке 7: In serialize (data, node $ con):
'package: MLmetrics' может быть недоступен при загрузке 8: In serialize(data, node$con): 'package:MLmetrics' может быть недоступен при загрузке

Сначала я загрузил библиотеку, но затем я запустил remove.packages(MLmetrics) перед запуском этого кода. Кроме того, я проверил конфликтующий:: конфликт_scout и не обнаружил никаких конфликтов с пакетом MLmetrics.

Когда я запускаю этот код

> mydf %>% 
+   filter(week == "2012-01-02")

Это дает мне этот результат

         week    value 
1: 2012-01-02      483     
2: 2012-01-02     61233  

Меня беспокоит, что что-то пошло не так, когда он группировал данные, поскольку он не создавал отдельных групп для недели значений. Оба столбца хранятся как символьные типы данных.

2 ответа

Решение

Автор {disk.frame} здесь.

Проблема в том, что в настоящее время {disk.frame} не группирует по withinкаждый кусок. Он не выполняет группировку по всему миру, как это делает синтаксис dplyr.

Поэтому вам нужно снова подвести итог, чтобы достичь того, чего вы хотите. Поэтому я предлагаю пока придерживаться синтаксиса dplyr.

Как отметил @Waldi, {disk.frame}Синтаксис dplyr работает нормально, и в настоящее время поддержка data.table отсутствует, поэтому на данный момент вы можете добиться только того, чего хотите, с помощью синтаксиса dplyr.

{disk.frame} должен реализовать https://github.com/xiaodaigh/disk.frame/issues/239, прежде чем он будет работать с data.table.

Пожалуйста, напишите мне, если кто-нибудь / организация захочет профинансировать разработку этой функции.

disk.frame выглядит интересным, чтобы заполнить пробел между обработкой RAM и большими данными.

Чтобы проверить это, я создал коллекцию из 200 * 200 МБ CSV-файлов общим объемом 40 ГБ сверх 32 ГБ оперативной памяти, установленной на моем компьютере:

library(furrr)
library(magrittr)
library(data.table)
libray(dplyr)
library(disk.frame)
plan(multisession,workers = 11)
nbrOfWorkers()
#[1] 11

filelength <- 1e7

# Create 200 files * 200Mb
sizelist <- 1:200 %>% future_map(~{
  mydf <- data.table(week = sample(1:52,filelength,replace=T),
                     list_of_id=sample(1:filelength,filelength,replace=T))
  filename <- paste0('data/test',.x,'.csv')
  data.table::fwrite(mydf, filename)
  write.csv(mydf,file=filename)
  file.size(filename)
})

sum(unlist(sizelist))
# [1] 43209467799

В виде distinct_n это dplyr глагол, я сначала остался в dplyr синтаксис:

setup_disk.frame()
#The number of workers available for disk.frame is 6
options(future.globals.maxSize = Inf)

mydf = csv_to_disk.frame(file.path('data',list.files('data')))
"
csv_to_disk.frame: Reading multiple input files.
Please use `colClasses = `  to set column types to minimize the chance of a failed read
=================================================

 ----------------------------------------------------- 
-- Converting CSVs to disk.frame -- Stage 1 of 2:

Converting 200 CSVs to 60 disk.frames each consisting of 60 chunks

 Progress: ──────────────────────────────────────────────────────────────── 100%

-- Converting CSVs to disk.frame -- Stage 1 or 2 took: 00:01:44 elapsed (0.130s cpu)
 ----------------------------------------------------- 
 
 ----------------------------------------------------- 
-- Converting CSVs to disk.frame -- Stage 2 of 2:

Row-binding the 60 disk.frames together to form one large disk.frame:
Creating the disk.frame at c:\TempWin\RtmpkNkY9H\file398469c42f1b.df

Appending disk.frames: 
 Progress: ──────────────────────────────────────────────────────────────── 100%

Stage 2 of 2 took: 59.9s elapsed (0.370s cpu)
 ----------------------------------------------------- 
Stage 1 & 2 in total took: 00:02:44 elapsed (0.500s cpu)"


result <- mydf %>% 
  group_by(week) %>% 
  summarize(value = n_distinct(list_of_id)) %>% 
  collect  

result
# A tibble: 52 x 2
    week   value
   <int>   <int>
 1     1 9786175
 2     2 9786479
 3     3 9786222
 4     4 9785997
 5     5 9785833
 6     6 9786013
 7     7 9786586
 8     8 9786029
 9     9 9785674
10    10 9786314
# ... with 42 more rows

Так что работает! Общий объем оперативной памяти, используемой для этой конкретной задачи, колебался от 1 до 5 ГБ, для 2 миллиардов строк на 6 процессорах потребовалось чуть меньше 10 минут, при этом ограничивающим фактором была скорость доступа к диску, а не производительность процессора.

Я также тестировал с data.table синтаксис, как disk.frame принимает оба, но я вернулся слишком быстро, в 60 раз больше строк (как если бы 60 disk.frames, созданные из 200 CSV, не были объединены и / или полностью обработаны), и много Warning messages: 1: In serialize(data, node$con).

Я отправил проблему на GitHub.
Пока это не прояснится, я предлагаю остаться с dplyr синтаксис, который работает.

Этот пример убедил меня, что disk.frameпозволяет обрабатывать данные больше RAM для поддерживаемых глаголов

Другие вопросы по тегам