【问题标题】:Why is a for loop on data.table row index slower than on data.frame?为什么 data.table 行索引上的 for 循环比 data.frame 上的慢?
【发布时间】:2014-01-28 18:28:27
【问题描述】:

对于为什么按行索引访问 data.table 比 data.frame 慢,我绝对感到困惑。有什么建议我可以更快地循环访问 data.table 的每一行?

m = matrix(1L, nrow=100000, ncol=100)

DF = as.data.frame(m)
DT = as.data.table(m)

identical(DF[100, ], DT[100, ])
[1] FALSE

> all(DF[100, ], DT[100, ])
[1] TRUE

> system.time(for (i in 1:1000) DT[i,])
   user  system elapsed 
  5.440   0.000   5.451 

R> system.time(for (i in 1:1000) DF[i,])
   user  system elapsed 
  2.757   0.000   2.784 

【问题讨论】:

  • 最简单的解释是[.data.table比[.data.frame做了更多的事情。
  • 如何才能更快地逐行索引迭代 data.frame 的行?
  • 我在这里创建了一个FR #5260。感谢您的报告。应该可以提高速度。
  • @user3147662,您为什么不通过遍历data.table 的行来提供有关您尝试解决的问题的更多信息?你可以在没有显式迭代的情况下做出惊人的强大的事情。此外,您可能应该将其作为一个单独的问题。
  • 一个很好的起点是用你的实际任务来编辑你的帖子,清楚地,用可生产的例子,并显示你的输出。

标签: r indexing dataframe data.table


【解决方案1】:

data.table 查询有更多参数(而且它做的更多),所以DT[...] 的小开销大于DF[...]。如果你循环它,这个开销就会增加。 data.table 的预期用途是让它执行几次大型复杂操作,而不是多次执行小的琐碎计算。所以让我们重新设计你的测试:

> system.time(DT[seq(len=nrow(m)),])
 user  system elapsed 
0.08    0.02    0.09 
> system.time(DF[seq(len=nrow(m)),])
 user  system elapsed 
0.08    0.05    0.13 

在这里,它们大致相同。由于我们只有一个 DT 调用,开销并不明显,因为开销只执行一次。在您的情况下,您执行了 100K 次(不必要,我可能会补充)。如果您使用data.table 并且您正在调用它数千次,那么您可能使用错误。几乎可以肯定有一种方法可以重新制定,这样您就可以只调用一个或几个 data.table 来做同样的事情。

另外,请注意,即使我在这里重新制定的测试也非常简单,这就是 data.table 的性能与 data.frame 相当的原因。

【讨论】:

  • 抱歉,您的第一行是什么意思?每个 data.table 语句的开销是多少?
  • [.data.table 解析时是 1000 行代码,而 [.data.frame 是 145。代码行数绝对不是开销的一个很好的比较,但显然 data.table 需要做更多比[.data.frame 对不同的输入做出适当的反应。这一点也不坏,它只是意味着如果你要使用data.table 进行一个完全微不足道的计算,并且每次都继续调用[.data.table,你会注意到与处理所有特殊条件相关的开销[data.table 管理。既然这不是数据表的正确用法,那不是问题
  • 一直都对。但是我们可以得到更多的加速。一旦我管理测试一些想法,我会回信。
  • 也许您应该将第一行编辑为您在评论中所说的内容。不清楚你在说[.data.table。
  • @Arun,您的意思是“[.data.table 是 1000 行代码...”开头的那一行吗?我很困惑。
猜你喜欢
  • 1970-01-01
  • 2017-11-09
  • 1970-01-01
  • 1970-01-01
  • 2019-12-08
  • 2014-02-17
  • 2014-07-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多