Вместо создания 2 временных dfs вы можете просто передать их как параметры в файле dict с помощью конструктора DataFrame:
pd.DataFrame({'email':sf.index, 'list':sf.values})
Существует множество способов построения df, см. docs
Мы могли бы внести эти изменения:
test$cummulative_time
могут быть просто cumulative_time
breaks
могут быть разложены и затем использованы в cut
, как показано mutate
может быть изменен на summarize
, в этом случае select
и distinct
не нужны group_by
с соответствующим ungroup
complete
, чтобы вставить 0 для уровней, которых нет Реализуя эти изменения, мы имеем:
library(dplyr)
library(tidyr)
breaks <- seq(0, 40, 10)
test %>%
mutate(bin_durations = cut(cumulative_time, breaks = breaks,
labels = breaks[-1], include.lowest = TRUE)) %>%
group_by(Id,bin_durations) %>%
summarize(total_duration = sum(duration)) %>%
ungroup %>%
complete(Id, bin_durations, fill = list(total_duration = 0))
, дающих: [ 1120]
# A tibble: 8 x 3
Id bin_durations total_duration
<dbl> <fct> <dbl>
1 1 10 1018
2 1 20 53
3 1 30 2175.
4 1 40 0
5 2 10 684
6 2 20 780
7 2 30 175
8 2 40 0
Вот одна идея с помощью целочисленного деления (%/%
)
library(tidyverse)
test %>%
group_by(Id, grp = cumulative_time %/% 10) %>%
summarise(toatal_duration = sum(duration))
, которая дает
blockquote># A tibble: 6 x 3 # Groups: Id [?] Id grp toatal_duration <dbl> <dbl> <dbl> 1 1 0 1018 2 1 1 53 3 1 2 2175. 4 2 0 684 5 2 1 780 6 2 2 175
. Для решения вашей обновленной проблемы мы можно использовать
complete
для добавления недостающих строк. Так, для того же примера, биннинг в часах 3,test %>% group_by(Id, grp = cumulative_time %/% 3) %>% summarise(toatal_duration = sum(duration)) %>% ungroup() %>% complete(Id, grp = seq(min(grp), max(grp)), fill = list(toatal_duration = 0))
, который дает,
blockquote># A tibble: 20 x 3 Id grp toatal_duration <dbl> <dbl> <dbl> 1 1 0 188 2 1 1 124 3 1 2 706 4 1 3 53 5 1 4 0 6 1 5 0 7 1 6 0 8 1 7 669 9 1 8 0 10 1 9 1506. 11 2 0 335 12 2 1 349 13 2 2 0 14 2 3 0 15 2 4 395 16 2 5 0 17 2 6 385 18 2 7 175 19 2 8 0 20 2 9 0