data.table:如何对部分密钥匹配执行最快范围查询?

时间:2015-07-31 23:56:27

标签: r data.table

在定义了键的data.table上。搜索键是键的部分匹配的范围查询有多快?示例:在大型data.table中(请参阅Q1的大小),获取具有姓氏键的行的子集,以" Jo"开始:

library(data.table)
set.seed(20150731)
dtUser <- data.table(
    Lastname=c("Jansen", "Jirovski", "Jocond", "Johnson", "Johnson", "Joule", "Jozef", "Jukanen", "Kanban"),
    UserID=sample(1:100, 9, replace=FALSE),
    key="Lastname")
#    Lastname UserID
# 1:   Jansen     77
# 2: Jirovski     69
# 3:   Jocond     24
# 4:  Johnson      7
# 5:  Johnson     27
# 6:    Joule     74
# 7:    Jozef      9
# 8:  Jukanen     54
# 9:   Kanban     78

#---Query1 (OK):
dtUser[Lastname > "Jo" & Lastname < "Ju",]
#    Lastname UserID
# 1:   Jocond     24
# 2:  Johnson      7
# 3:  Johnson     27
# 4:    Joule     74
# 5:    Jozef      9

#---Query2 (Failed):
dtUser[J("Jo"),]
#    Lastname UserID
# 1:       Jo     NA

问题1 :data.table大小可能很大(在100万到1000万行之间,最多100个字节/行。)快速性能至关重要。 Query1是最快的方式吗?

问题2 :如果data.table不适合&#34;超快&#34;部分密钥匹配的范围查询搜索。 R中最合适的数据结构是什么?

测试结果:在1.2GB数据集上使用Query1:40万行数据表,4个cols(Str1,Str2,Str3,BogusInteger)。 StrX这里是独特的短字符串,平均长度为10个字符,类似于人姓。

c(nbRows=nrow(myDT), "SizeMB"=round(object.size(myDT) / 1e6, 0))
#   nbRows   SizeMB
# 39480360     1208

setkey(myDT, Str1, Str2, Str3)

# Partial key match (slower)
system.time(dtTest <- myDT[Str1 > "tranbar" & Str1 < "tranbaz", ])
system.time(dtTest <- myDT[Str1 > "int" & Str1 < "intz" & Str2 > "mo" & Str2 < "mu", ])
system.time(dtTest <- myDT[Str1 > "int" & Str1 < "intz" & Str2 > "mo" & Str2 < "mu" & Str3 > "t" & Str3 < "u", ])

# Exact key match (faster)
system.time(dtTest <- myDT[Str1 == "transportation", ])
system.time(dtTest <- myDT[Str1 == "transportation" & Str2 == "energy", ])
system.time(dtTest <- myDT[Str1 == "transportation" & Str2 == "energy" & Str2 == "costs", ])
  • 电脑:台式机,8GB内存,CPU:Q9550,Xubuntu 14.04 x64
  • R 3.20,RStudio 0.99.446
  • data.table 1.9.4
  • 部分密钥匹配:无论返回的行数是多少,每个列的查询持续时间大约为11秒(在我的各种测试中,从200,000到5行甚至是0)
  • 精确密钥匹配:更快,几乎立即为1列。
  • 单独查询Str1列:平均时间11秒(部分),0.02秒(精确)
  • 查询Str1&amp; Str2:平均时间23秒(部分),3.2秒(精确)
  • 查询Str1&amp; Str2&amp; Str3:平均时间35秒(部分),5.3秒(精确)

0 个答案:

没有答案