在data.table中有条件替换数据值的最快方法(速度比较)

2023-11-21

为什么第二种方法会因增加data.table大小而变慢:

library(data.table)
DF = data.table(x=rep(c("a","b","c"),each=40000000), y=sample(c(1,3,6),40000000,T), v=1:9)

1:

DF1=DF2=DF

system.time(DF[y==6,"y"]<-10)
user  system elapsed 
2.793   0.699   3.497 

2:

system.time(DF1$y[DF1$y==6]<-10)
user  system elapsed 
6.525   1.555   8.107 

3:

system.time(DF2[y==6, y := 10]) # slowest!
user  system elapsed 
7.925   0.626   8.569 

>sessionInfo()
R version 3.2.1 (2015-06-18)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 14.04.3 LTS

有没有更快的方法来做到这一点?


在你的最后一个案例中,这是由于自动索引特色于data.table,自 v1.9.4+ 起。阅读更多内容以获取完整图片:-)。

当你这样做时DT[col == .] or DT[col %in% .],正在自动生成索引你的第一次跑步。索引只是order您指定的列的。索引的计算非常快(使用计数排序/真基数排序)。

该表有 1.2 亿行,大约需要:

# clean session
require(data.table)
set.seed(1L)
DF = data.table(x=rep(c("a","b","c"),each=40000000), y=sample(c(1,3,6),40000000,T), v=1:9)

system.time(data.table:::forderv(DF, "y"))
#   3.923   0.736   4.712 

边注: Column y不一定是真的double(订购时间较长)。如果我们将其转换为整数类型:

   DF[, y := as.integer(y)]
   system.time(data.table:::forderv(DF, "y"))
   #    user  system elapsed 
   #   0.569   0.140   0.717 

优点是该列上的任何后续子集使用== or %in%将会非常快(Slides, R script, video马特的演讲)。例如:

# clean session, copy/paste code from above to create DF
system.time(DF[y==6, y := 10])
#    user  system elapsed 
#   4.750   1.121   5.932 

system.time(DF[y==6, y := 10])
#    user  system elapsed 
#   4.002   0.907   4.969 

哦等一下..它并不快。但是..索引..?!?我们每次都会用新值替换同一列。这会导致该列的顺序发生更改(从而删除索引)。让我们子集化y,但修改v:

# clean session
require(data.table)
set.seed(1L)
DF = data.table(x=rep(c("a","b","c"),each=40000000), y=sample(c(1,3,6),40000000,T), v=1:9)

system.time(DF[y==6, v := 10L])
#    user  system elapsed 
#   4.653   1.071   5.765 
system.time(DF[y==6, v := 10L])
#    user  system elapsed 
#   0.685   0.213   0.910 

options(datatable.verbose=TRUE)
system.time(DF[y==6, v := 10L])
# Using existing index 'y'
# Starting bmerge ...done in 0 secs
# Detected that j uses these columns: v 
# Assigning to 40000059 row subset of 120000000 rows
#    user  system elapsed 
#   0.683   0.221   0.914 

您可以看到计算索引(使用二分搜索)的时间为 0 秒。另请检查?set2key().

如果您不打算重复进行子集化,或者像您的情况一样,对同一列进行子集化和修改,那么通过执行以下操作来禁用该功能是有意义的options(datatable.auto.index = FALSE), filed #1264:

# clean session
require(data.table)
options(datatable.auto.index = FALSE) # disable auto indexing
set.seed(1L)
DF = data.table(x=rep(c("a","b","c"),each=40000000), y=sample(c(1,3,6),40000000,T), v=1:9)

system.time(DF[y==6, v := 10L])
#    user  system elapsed 
#   1.067   0.274   1.367 
system.time(DF[y==6, v := 10L])
#    user  system elapsed 
#   1.100   0.314   1.443 

这里差别不大。矢量扫描的时间为system.time(DF$y == 6) = 0.448s.

总而言之,就你的情况而言,矢量扫描更有意义。但总的来说,最好是一次性支付惩罚,并在该列的未来子集上快速获得结果,而不是每次都进行矢量扫描。

自动索引功能相对较新,并且会随着时间的推移而扩展,并且可能会进行优化(也许有些地方我们没有看过)。在回答这个问题时,我意识到我们没有显示计算排序顺序的时间(使用fsort(),我猜在那里花费的时间可能是时间非常接近的原因,提交#1265).


至于你的第二种情况很慢,不太清楚为什么。我怀疑这可能是由于 R 部分的不必要的副本所致。您使用什么版本的 R?为了将来,请始终发布您的sessionInfo() output.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在data.table中有条件替换数据值的最快方法(速度比较) 的相关文章

随机推荐

  • 根据ID在jquery中设置单选按钮“选中”

    我有两个同名的单选按钮 默认情况下选中一个 从 id 选择时如何选中或取消选中 jQuery 中的单选按钮 我试过了 radio1 attr checked checked radio1 attr checked true 似乎没有任何作用
  • ALLOWED_HOSTS 正在防御什么漏洞?

    该示例来自 Python Django 框架 但适用于所有 Web 应用程序 如何ALLOWED HOSTS setting保护您的网站和用户 即如果ALLOWED HOSTS被设置为 恶意用户将如何 毒害带有恶意主机链接的缓存和密码重置电
  • 对三个对象使用“==”运算符

    这两种检查三个对象之间相等性的方法之间是否存在计算差异 我有两个变量 x and y 假设我这样做 gt gt gt x 5 gt gt gt y 5 gt gt gt x y 5 True 这与以下有什么不同 gt gt gt x 5 g
  • 如何克隆 JPA 实体

    我有一个 JPA 实体已保存在数据库中 我想要一份它的副本 具有不同的 ID 并修改了一些字段 做到这一点最简单的方法是什么 喜欢 设置它的 Id字段到null并且坚持下去会有效果吗 我是否必须为实体创建一个克隆方法 复制除 Id 还有其他
  • 在javascript中计算单词并将其推入一个对象中

    我想实现一个 javascript 程序 计算一个单词并返回该单词及其出现的次数 例如 hello 2 hello 1 world 1 toString 1 下面是我的代码 但我只得到总字数 function words str app r
  • 如何在express.js中抛出404错误?

    在 app js 中 我有 catch 404 and forward to error handler app use function req res next var err new Error Not Found err statu
  • 在运行时将图像添加到 Crystal Report

    我想在运行时将图像添加到水晶报告中 我目前正在使用第二个数据表来执行此操作 其中仅包含一个字节字段 然后在报告上包含一个 blob 字段 然而 这感觉就像一个黑客 如果第一个主表中没有数据 那么由于某种原因图像不会显示 是否可以使用代码或其
  • Web应用程序后台进程,新手设计问题

    经过多年的桌面应用程序开发 我正在构建我的第一个 Web 应用程序 我正在使用 Django Python 但也许这是一个完全通用的问题 我不确定 所以请注意 这可能是一个超级新手问题 我的一个用户进程涉及服务器中的繁重处理 即用户输入一些
  • WPF TreeView 双击后恢复焦点

    我有一个带有 XAML 的 WPF TreeView 如下所示
  • 错误:缺少分隔符

    我运行时遇到以下错误make Makefile 168 missing separator Stop 是什么原因造成的 如中所示在线手册 该错误的最常见原因是行在以下情况下缩进空格 make需要制表符 Correct target tcmd
  • 在 Windows 通用应用程序中检测当前设备

    我正在尝试发布的 VS 2013 Update 2 并构建一个示例通用应用程序 我创建了一个用户控件 并在两个 MainPages 上添加了 GridView 在 Windows Phone 和 Windows 8 上 当应用程序在 Win
  • TypeScript 类装饰器 - 添加类方法

    如何使用 TypeScript 和装饰器定义属性 例如我有这个类装饰器 function Entity
  • R 绘图悬停标签文本对齐

    我正在为 R 中的绘图中的散点图点添加自定义悬停文本 它似乎将文本左对齐 居中或右对齐 具体取决于文本框是否显示在图的右侧 中心或左侧点 分别 我希望文本始终左对齐 无论框的位置如何 我已经能够设置字体的样式 例如设置颜色和大小 但无法更改
  • 获取 NSDate 今天、昨天、本周、上周、本月、上个月...变量

    我想做的是让 NSDate 今天 昨天 本周 上周 本月 上个月变量准备好进行比较 以便在 UITableView 的 titleForHeaderInSection 上添加标题 我想要的是在下面的代码中手动完成日期 2009 12 11
  • 在 SearchView 中限制 onQueryTextChange

    最好的 节流 方式是什么onQueryTextChange这样我的performSearch 方法每秒仅调用一次 而不是每次用户键入时调用 public boolean onQueryTextChange final String newT
  • 当设置 Perl 代码作为脚本或模块运行时,__PACKAGE__ 的原因是什么?

    In this 较早的 Stackoverflow 问题尤其是brian d foy 的 脚本如何成为模块 我已经阅读了如何使用以下技术设置代码 以便它可以作为脚本或模块运行 package SomeModule PACKAGE gt ru
  • Eigen 在小矩阵相乘方面很慢吗?

    我编写了一个函数 将 10x10 维的特征矩阵相乘 然后我写了一个简单的乘法函数CustomMultiply令人惊讶的是 这比 Eigen 的实现快了 2 倍 我尝试了几个不同的编译标志 例如 O2 和 O3 但没有什么区别 include
  • 有没有什么方法可以在 Windows 64 位上的 Postgresql 9.3 64 位或 32 位中成功安装 PLPython?

    running CREATE EXTENSION plpython3u给了我错误 The specified module could not be found即使文件位于正确的位置 阅读完网上的所有内容后 我尝试按照建议下载另一个 pyt
  • 托管 Linux 预览代理上的缓存 Docker 映像

    我们正在使用 VSTS 托管 Linux 预览代理在 VSTS 上构建 docker 映像 microsoft aspnetcore build 镜像用于构建 asp net core 应用程序 每次触发构建时 代理都会从注册表中提取 mi
  • 在data.table中有条件替换数据值的最快方法(速度比较)

    为什么第二种方法会因增加data table大小而变慢 library data table DF data table x rep c a b c each 40000000 y sample c 1 3 6 40000000 T v 1