Нужно ли использовать сбор с дисковыми фреймами?

Этот вопрос является продолжением этой темы

Я хочу выполнить три действия с фреймом диска

  1. Подсчитайте различные значения поля id сгруппированы по двум столбцам (key_a и key_b)
  2. Подсчитайте различные значения поля id сгруппированы по первому из двух столбцов (key_a)
  3. Добавьте столбец с отдельными значениями для первого столбца / различными значениями в обоих столбцах

Это мой код

      my_df <-
        data.frame(
          key_a = rep(letters, 384),
          key_b = rep(rev(letters), 384),
          id = sample(1:10^6, 9984)
        )
      
      my_df %>% 
        select(key_a, key_b, id) %>% 
        chunk_group_by(key_a, key_b) %>% 
        # stage one
        chunk_summarize(count = n_distinct(id)) %>% 
        collect %>% 
        group_by(key_a, key_b) %>% 
        # stage two
        mutate(count_summed = sum(count)) %>%
        group_by(key_a) %>% 
        mutate(count_all = sum(count)) %>% 
        ungroup() %>% 
        mutate(percent_of_total = count_summed / count_all)

Мои данные имеют формат фрейма диска, а не фрейма данных, и имеют 100 млн строк и 8 столбцов.

Я следую двухэтапным инструкциям, описанным в этой документации.

Я обеспокоен тем, что collect сломает мою машину, так как она все доводит до тарана

Я должен использовать collect чтобы использовать dplyr group bys во фрейме диска?

1 ответ

Решение

Вы всегда должны использовать srckeep чтобы загрузить в память только те столбцы, которые вам нужны.

my_df %>% 
        srckeep(c("key_a", "key_b", "id")) %>%
        # select(key_a, key_b, id) %>% # no need if you use srckeep
        chunk_group_by(key_a, key_b) %>% 
        # stage one
        chunk_summarize(count = n_distinct(id)) %>% 
        collect %>% 
        group_by(key_a, key_b) %>% 
        # stage two
        mutate(count_summed = sum(count)) %>%
        group_by(key_a) %>% 
        mutate(count_all = sum(count)) %>% 
        ungroup() %>% 
        mutate(percent_of_total = count_summed / count_all)

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

Вы должны использовать collect как и другие системы, такие как Spark.

Но если вы вычисляете n_distinct, это в любом случае можно сделать за один этап

 my_df %>% 
        srckeep(c("key_a", "key_b", "id")) %>%
        #select(key_a, key_b, id) %>% 
        group_by(key_a, key_b) %>% 
        # stage one
        summarize(count = n_distinct(id)) %>% 
        collect

Если вас действительно беспокоит использование ОЗУ, вы можете уменьшить количество рабочих до 1

setup_disk.frame(workers=1)
my_df %>% 
        srckeep(c("key_a", "key_b", "id")) %>%
        #select(key_a, key_b, id) %>% 
        group_by(key_a, key_b) %>% 
        # stage one
        summarize(count = n_distinct(id)) %>% 
        collect

setup_disk.frame()
Другие вопросы по тегам