首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >multidplyr和group_by ()和filter()

multidplyr和group_by ()和filter()
EN

Stack Overflow用户
提问于 2017-07-30 11:35:47
回答 1查看 2.2K关注 0票数 9

我有下面的dataframe,我的目的是查找所有的is,它们的用法不同,但类型相同。

代码语言:javascript
复制
ID <- rep(1:4, each=3)
USAGE <- c("private","private","private","private",
"taxi","private","taxi","taxi","taxi","taxi","private","taxi")
TYPE <- c("VW","VW","VW","VW","MER","VW","VW","VW","VW","VW","VW","VW")
df <- data.frame(ID,USAGE,TYPE)

如果我跑了

代码语言:javascript
复制
df %>% group_by(ID, TYPE) %>% filter(n_distinct(USAGE)>1)

我得到了预期的结果。但是我的原始数据帧有>2000万行。所以我想用我所有的核心来运行这个操作。

我用multidplyr尝试了这段代码:

代码语言:javascript
复制
f1 <- partition(df, ID)
f2 <- f1 %>% group_by(ID, TYPE) %>% filter(n_distinct(USAGE)>1)
f3 <- collect(f2)

但随后出现了以下信息:

代码语言:javascript
复制
Warning message: group_indices_.grouped_df ignores extra arguments

之后

代码语言:javascript
复制
f1 <- partition(df, ID)

代码语言:javascript
复制
Error in checkForRemoteErrors(lapply(cl, recvResult)) : 
  4 nodes produced errors; first error: Evaluation error: object 'f1' not found.

之后

代码语言:javascript
复制
f2 <- f1%>% group_by(ID, TYPE) %>% filter(f1, n_distinct(USAGE)>1)

将整个操作实现为multidplyr的正确方法是什么?非常感谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-15 15:20:36

您应该在对partition()的调用中包含所有分组变量。这样,每个核心都有为给定组执行计算所需的所有数据。

代码语言:javascript
复制
library(tidyverse)
library(multidplyr)

fast <- df %>%
  partition(ID, TYPE) %>%
  group_by(ID, TYPE) %>%
  filter(n_distinct(USAGE) > 1) %>%
  collect()

验证

您仍然会得到关于group_indices的警告,但是结果与原始的dplyr方法相同。

代码语言:javascript
复制
slow <- df %>%
  group_by(ID, TYPE) %>%
  filter(n_distinct(USAGE) > 1)

fast == slow
       ID USAGE TYPE
#[1,] TRUE  TRUE TRUE
#[2,] TRUE  TRUE TRUE
#[3,] TRUE  TRUE TRUE

基准测试

现在最大的问题是:它会更快吗?定义cluster可以让我们确保我们正在使用所有的核心。

代码语言:javascript
复制
library(microbenchmark)
library(parallel)

cluster <- create_cluster(cores = detectCores())

fast_func <- function(df) {
  df %>%
    partition(ID, TYPE, cluster = cluster) %>%
    group_by(ID, TYPE) %>%
    filter(n_distinct(USAGE) > 1) %>%
    collect()
}

slow_func <- function(df) {
  slow <- df %>%
    group_by(ID, TYPE) %>%
    filter(n_distinct(USAGE) > 1)
}

microbenchmark(fast_func(df), slow_func(df))
# Unit: milliseconds
# expr       min        lq      mean    median        uq       max neval cld
# fast_func(df) 41.360358 47.529695 55.806609 50.529851 61.459433 133.53045   100   b
# slow_func(df)  4.717761  6.974897  9.333049  7.796686  8.468594  49.51916   100  a 

在这种情况下,使用并行处理实际上是较慢的fast_func的平均运行时间为56毫秒,而不是9毫秒,这是因为与管理跨集群数据流相关的开销。但是您说您的数据有数百万行,所以让我们来试试。

代码语言:javascript
复制
# Embiggen the data
df <- df[rep(seq_len(nrow(df)), each=2000000),] %>% tbl_df()

microbenchmark(fast_func(df), slow_func(df))
# Unit: seconds
# expr       min        lq      mean    median        uq       max neval cld
# fast_func(df) 43.067089 43.781144 50.754600 49.440864 55.308355 65.499095    10   b
# slow_func(df)  1.741674  2.550008  3.529607  3.246665  3.983452  7.214484    10  a 

对于巨大的数据集,fast_func仍然是慢的!有时候并行运行会节省大量的时间,但是简单的分组过滤器并不一定是其中之一。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45399366

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档