简单测一下dplyr

R 语言处理数据的一大优势就是它自身有非常多方便的函数可以对 data.frame 进行各种变换。 这其中 Hadley 的 plyr 包可谓一大神器。很多时候一个 ddply 函数加上 subset, merge 就可以搞定大多数需求。

不过这些操作的性能问题也一直被人诟病。 好消息是 Hadley 新的 dplyr 包在这方面有了巨大的提升, 大量底层操作用 C++ 改写。这里简单测一下常用的 groupby 和 join(merge) 功能,并顺便跟 python 的 pandas 做对比。

group by

测试取的数据集(下文中的S)大概5000多万行,1G大小。

plyr 包在 group by 分组数量较小时还能忍受,但还是比 dplyr 慢很多。 (用 microbenchmark 包测多次的结果也是类似的,那个输出比较长,以下只贴 system.time 的结果)

system.time(A <- ddply(S, .(status), summarise, cnt = length(uid)))
user  system elapsed
9.348   5.652  15.034

system.time(S %>% group_by(status) %>% summarise(cnt = n()) -> A)
user  system elapsed
1.928   0.500   2.502

这里 status 列的不同值只有个位数。如果对于用户 id 或条目 id 这种变量进行 group by 的话,plyr 会非常非常慢。 在测试数据集上直接运行到500多秒报错。下面是 dplyr 跟 pandas 的对比结果。

system.time(S %>% group_by(eid) %>% summarise(cnt = n()) -> A)
user  system elapsed
5.268   0.424   5.704

In [41]: %timeit A = S.groupby('eid').uid.count()
1 loops, best of 3: 3.22 s per loop

可以看到 pandas 还是要快一些。不过如果对多个变量进行 group by,两者的差距就可以忽略不计了,甚至 R 还要快一点。

system.time(S %>% group_by(eid, status) %>% summarise(cnt = n()) -> B)
user  system elapsed
8.168   0.288   8.470

In [42]: %timeit B = S.groupby(['eid', 'status']).uid.count()
1 loops, best of 3: 8.88 s per loop

merge

另外取了一个数据集来测试 merge 功能(下文中的M),文件大致有200万行。

因为 R 自身的 merge 对于大数据确实比较慢,这里就只测 dplyr 和 pandas:

system.time(R1 <- inner_join(S, M))
Joining by: "uid"
user  system elapsed
18.616   0.812  19.487

In [20]: %timeit R = pd.merge(S, M, on = 'uid')
1 loops, best of 3: 21.1 s per loop

可以看到在 merge 功能上 dplyr 有时也还是要比 pandas 快那么一点点。

顺便提一句,dplyr 中新加入的 semi_join 函数非常实用。 原先需要通过向量化 index 方法实现的一些抽取过滤现在可以一句话搞定了。

其他

更多的功能测试有空再试吧。可能身边的 python 党们更习惯直接过渡到 pandas,但是个人的使用感觉还是 R 更简便。 主要是语法和功能上,至于运行效率,我个人接触过的例子,到了分析这步,数据量往往都是在 10G 甚至 1G 以下, 这个时候服务器端的 R 已经可以比较好地完成任务了,而且随着 dplyr 等包的发展,跟 pandas 比劣势已经很小了。 加上 R 自身完整的统计生态环境,和 ggplot2, shiny, knitr, recharts 等利器, 搞个可视化也好,搭个网页 app 做带交互的 demo 搞 presentation 也好,写可重复分析报告也好,都是分分钟的事。

F. Shen
F. Shen
Algorithm Engineer

Be an informed citizen, life hacker, and sincere creator.

comments powered by Disqus
Next
Previous

Related