164

我最近遇到了python 的pandas库,根据这个基准,它执行非常快速的内存合并。它甚至比 R 中的data.table包(我选择的分析语言)还要快。

为什么pandas比 快那么多data.table?是因为 python 比 R 具有固有的速度优势,还是有一些我不知道的权衡?有没有办法在data.table不诉诸merge(X, Y, all=FALSE)and的情况下执行内部和外部联接merge(X, Y, all=TRUE)

比较

这是用于对各种包进行基准测试的R 代码Python 代码。

4

4 回答 4

191

pandas 更快的原因是因为我想出了一个更好的算法,它使用快速哈希表实现 - klib和 C/ Cython非常仔细地实现,以避免非矢量化部分的 Python 解释器开销。该算法在我的演示文稿中进行了详细描述:A look inside pandas design and development

与 的比较data.table实际上有点有趣,因为 R 的重点data.table在于它包含各种列的预计算索引,以加速数据选择和合并等操作。在这种情况下(数据库连接),pandas 的 DataFrame 不包含用于合并的预先计算的信息,可以说这是一个“冷”合并。如果我存储了连接键的分解版本,连接会明显更快——因为分解是该算法的最大瓶颈。

我还应该补充一点,pandas 的 DataFrame 的内部设计比 R 的 data.frame(它只是内部数组的列表)更适合这些类型的操作。

于 2012-01-24T19:17:34.530 回答
124

看起来 Wes 可能在data.table唯一字符串 ( levels ) 的数量很大时发现了一个已知问题:10,000。

是否Rprof()显示大部分时间都在通话中sortedmatch(levels(i[[lc]]), levels(x[[rc]])?这并不是真正的连接本身(算法),而是一个初步步骤。

最近的努力已经进入允许键中的字符列,这应该通过与 R 自己的全局字符串哈希表更紧密地集成来解决这个问题。一些基准测试结果已被报告,test.data.table()但该代码尚未连接以将级别替换为级别匹配。

pandas 的合并速度是否比data.table常规整数列快?这应该是一种隔离算法本身与因素问题的方法。

此外,data.table考虑时间序列合并。两个方面:i) 多列有序键,例如 (id,datetime) ii) 快速流行的连接 ( roll=TRUE),也就是最后的观察结果。

我需要一些时间来确认,因为这是我第一次看到与data.table所呈现的比较。


2012 年 7 月发布的 data.table v1.8.0 的更新

  • 当将 i 级别匹配到“因子”类型的列的 x 级别时,内部函数 sortedmatch() 被删除并替换为 chmatch()。当因子列的水平数很大(例如>10,000)时,这个初步步骤会导致(已知的)显着放缓。正如 Wes McKinney(Python 包 Pandas 的作者)所证明的那样,在加入四个这样的列的测试中加剧了这种情况。例如,匹配 100 万个字符串,其中 600,000 个是唯一的,现在从 16 秒减少到 0.5 秒。

在那个版本中还有:

  • 现在允许在键中使用字符列,并且优先考虑因素。data.table() 和 setkey() 不再强制字符为因子。因素仍然得到支持。实现 FR#1493、FR#1224 和(部分)FR#951。

  • 新函数 chmatch() 和 %chin%,match() 和 %in% 用于字符向量的更快版本。使用了 R 的内部字符串缓存(没有构建哈希表)。它们比 ?chmatch 中的示例中的 match() 快约 4 倍。

截至 2013 年 9 月,data.table 在 CRAN 上是 v1.8.10,我们正在开发 v1.9.0。新闻实时更新。


但正如我最初写的那样,上面:

data.table考虑到时间序列合并。两个方面:i) 多列有序键,例如 (id,datetime) ii) 快速流行的连接 ( roll=TRUE),也就是最后的观察结果。

因此,两个字符列的 Pandas equi join 可能仍然比 data.table 快。因为它听起来像是对合并的两列进行哈希处理。data.table 不会散列密钥,因为它考虑了普遍的有序连接。data.table 中的“键”实际上只是排序顺序(类似于 SQL 中的聚集索引;即,这就是数据在 RAM 中的排序方式)。例如,在列表中添加辅助键。

总之,这个具有超过 10,000 个唯一字符串的特殊两字符列测试突出显示的明显速度差异现在应该不会那么糟糕,因为已知问题已得到修复。

于 2012-01-25T04:42:42.983 回答
39

这个话题已经有两年的历史了,但是当人们搜索 Pandas 和 data.table 的比较时,这似乎是一个可能的落脚点

由于这两者都随着时间的推移而发展,我想在这里为感兴趣的用户发布一个相对较新的比较(从 2014 年开始):https ://github.com/Rdatatable/data.table/wiki/Benchmarks-:-Grouping

想知道 Wes 和/或 Matt(顺便说一句,他们分别是 Pandas 和 data.table 的创建者并且都在上面发表过评论)是否也有任何新闻要添加到这里会很有趣。

- 更新 -

jangorecki 在下面发布的评论包含一个我认为非常有用的链接:https ://github.com/szilard/benchm-databases

https://github.com/szilard/benchm-databases/blob/master/plot.png

该图描述了不同技术的聚合和连接操作的平均时间(较低 = 更快;比较最后更新于 2016 年 9 月)。这对我来说真的很有教育意义。

回到这个问题,R DT key参考R DTR 的 data.table 的键控/非键控风格,在这个基准测试中碰巧比 Python 的 Pandas ( Py pandas) 更快。

于 2015-09-09T22:09:14.963 回答
11

有很好的答案,特别是由问题所问的两种工具的作者提出的。马特的回答解释了问题中报告的情况,它是由错误引起的,而不是由合并算法引起的。第二天就修复了错误,已经超过 7 年了。

在我的回答中,我将为 data.table 和 pandas 提供一些最新的合并操作时间。请注意,不包括 plyr 和 base R 合并。

我介绍的时间来自db-benchmark项目,这是一个连续运行的可重现基准。它将工具升级到最新版本并重新运行基准脚本。它运行许多其他软件解决方案。如果您对 Spark、Dask 和其他少数人感兴趣,请务必查看链接。


截至目前...(仍有待实施:增加一个数据量和另外 5 个问题)

我们测试了 LHS 表的 2 种不同数据大小。
对于这些数据大小中的每一个,我们运行 5 个不同的合并问题。

q1:LHS内连接 RHS- small 整数
q2:LHS 内连接 RHS-medium 整数
q3:LHS连接 RHS-medium 整数
q4:LHS 内连接 RHS-medium因子(分类)
q5:LHS 内连接 RHS- 整数

RHS 表有 3 种不同的尺寸

  • small转换为 LHS/1e6 的大小
  • medium转换为 LHS/1e3 的大小
  • big转换为 LHS 的大小

在所有情况下,LHS 和 RHS 之间大约有 90% 的匹配行,并且在 RHS 连接列中没有重复(没有笛卡尔积)。


截至目前(2019 年 11 月 2 日运行)

pandas 0.25.3 于 2019 年 11 月 1 日发布
data.table 0.12.7 (92abb70) 于 2019 年 11 月 2 日发布

以下时间以秒为单位,用于 LHS 的两种不同数据大小。列pd2dt增加了pandas比data.table慢多少倍的字段存储比例。

  • 0.5 GB LHS 数据
+-----------+--------------+----------+--------+
| question  |  data.table  |  pandas  |  pd2dt |
+-----------+--------------+----------+--------+
| q1        |        0.51  |    3.60  |      7 |
| q2        |        0.50  |    7.37  |     14 |
| q3        |        0.90  |    4.82  |      5 |
| q4        |        0.47  |    5.86  |     12 |
| q5        |        2.55  |   54.10  |     21 |
+-----------+--------------+----------+--------+
  • 5 GB LHS 数据
+-----------+--------------+----------+--------+
| question  |  data.table  |  pandas  |  pd2dt |
+-----------+--------------+----------+--------+
| q1        |        6.32  |    89.0  |     14 |
| q2        |        5.72  |   108.0  |     18 |
| q3        |       11.00  |    56.9  |      5 |
| q4        |        5.57  |    90.1  |     16 |
| q5        |       30.70  |   731.0  |     23 |
+-----------+--------------+----------+--------+
于 2019-11-05T15:51:37.520 回答