【问题标题】:Slow data.table subsetting vs dplyr缓慢的 data.table 子集与 dplyr
【发布时间】:2018-03-20 04:01:44
【问题描述】:

我一直在使用以下格式的dplyr代码

 group_by(dt, ID) %>%
    filter(any(colY == 1 & colX == 10))

像下面这样子集一个data.table

ID colX colY 1111 3 1 1111 2 1 1111 6 0 1111 9 0 2222 10 1 2222 3 1 2222 5 0 2222 7 0 3333 8 1 3333 10 1 3333 3 0 3333 2 0

进入

ID colX colY 2222 10 1 2222 3 1 2222 5 0 2222 7 0 3333 8 1 3333 10 1 3333 3 0 3333 2 0

过滤大约 900k 行得到第二个表大约需要 1.3 秒。

我一直在尝试实现一个更快的 data.table 子集,但到目前为止,结果只需要更长的时间。使用以下 data.table 子集

dt[ , .SD[any( (colY == 1 & colX == 10)) ], ID]

大约需要 14 秒。这里似乎有什么问题?

【问题讨论】:

  • , 10] 是您的ID 列位置吗?也许您会生成一些模拟数据,以便为您轻松地对现实解决方案进行基准测试。
  • 抱歉应该按 ID 分组

标签: r data.table


【解决方案1】:

这可能会更快。它避免使用.SD,而是使用.I 中给出的行号。

dt[dt[, .I[any(colX == 10 & colY == 1)], by = ID]$V1]
#      ID colX colY
# 1: 2222   10    1
# 2: 2222    3    1
# 3: 2222    5    0
# 4: 2222    7    0
# 5: 3333    8    1
# 6: 3333   10    1
# 7: 3333    3    0
# 8: 3333    2    0

内部数据表调用dt[, .I[any(colX == 10 & colY == 1)], by = ID]$V1 为我们提供了符合我们条件的那些组的行号。 .I 为我们提供了每组的行位置。我们可以通过打印我们的调用来查看结果:

dt[, print(.I[any(colX == 10 & colY == 1)]), by = ID]
# integer(0)
# [1] 5 6 7 8
# [1]  9 10 11 12
# Empty data.table (0 rows) of 1 col: ID

然后我们只使用该结果作为原始数据表上的行子集。

【讨论】:

  • 这最终比我尝试的 data.table 子集快 75 倍。 .SD 正在拉动 90k 组,这大大减慢了进程
  • 加入是另一种方式,如果有很多组可能会更快DT[.(DT[.(1,10), on=c("colY","colX"), unique(ID)]), on="ID"] 将此添加到我的链接堆中以获得having= 参数github.com/Rdatatable/data.table/issues/788
猜你喜欢
  • 1970-01-01
  • 2014-04-25
  • 2013-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-08
  • 2011-07-26
  • 1970-01-01
相关资源
最近更新 更多