【问题标题】:Verify that the key of a data.table is unique验证 data.table 的键是否唯一
【发布时间】:2017-04-01 07:41:57
【问题描述】:

验证data.table 的密钥是否唯一的最快方法是什么?有没有比

更快或更惯用的方式
has_unique_key <- function(.data){
  uniqueN(.data, by = key(.data)) == nrow(.data)
}

为了避免开销性能成本,该函数可以假设.datadata.table 并且有一个密钥。我对验证.data 具有唯一密钥的性能更感兴趣;如果密钥不是唯一的,那么速度就不那么重要了。

小插图Keys and fast binary search based subset 指出密钥唯一性未强制执行:

  1. 不强制唯一性,即允许重复的键值。由于行是按键排序的,因此键列中的任何重复项都会连续出现。

但我没有发现任何表明 data.table 知道或不知道其密钥是唯一的。

唯一键

set.seed(1)
z <- sample(1:1e5)
DT <- data.table(z = z) 
setkey(DT, z)
DT[, a := sample(letters, nrow(DT), replace = TRUE)]
DT[, b := rnorm(.N)]

microbenchmark(nrow(DT) == nrow(unique(DT, by = key(DT))),
               uniqueN(DT[, key(DT), with=F]) == nrow(DT),
               uniqueN(DT, by = key(DT)) == nrow(DT))

Unit: microseconds
                                         expr      min       lq     mean   median       uq      max neval cld
   nrow(DT) == nrow(unique(DT, by = key(DT))) 1731.766 2786.937 3678.377 3152.114 3870.119 9875.277   100   c
 uniqueN(DT[, key(DT), with = F]) == nrow(DT)  777.637 1113.149 1543.786 1276.236 1614.307 3809.281   100  b 
        uniqueN(DT, by = key(DT)) == nrow(DT)  541.515  734.570 1123.801  825.826 1756.612 2356.406   100 a  

不是唯一的

set.seed(1)
z <- c(1e5, sample(1:1e5))
DT <- data.table(z = z) 
setkey(DT, z)
DT[, a := sample(letters, nrow(DT), replace = TRUE)]
DT[, b := rnorm(.N)]

microbenchmark(nrow(DT) == nrow(unique(DT, by = key(DT))),
               uniqueN(DT[, key(DT), with=F]) == nrow(DT),
               uniqueN(DT, by = key(DT)) == nrow(DT))

Unit: microseconds
                                         expr      min       lq     mean   median       uq       max neval cld
   nrow(DT) == nrow(unique(DT, by = key(DT))) 2925.026 4051.878 5340.941 4535.266 5464.095 12479.852   100   c
 uniqueN(DT[, key(DT), with = F]) == nrow(DT) 1148.688 1515.972 1875.423 1670.627 1981.892  4843.822   100  b 
        uniqueN(DT, by = key(DT)) == nrow(DT)  857.450 1018.580 1332.697 1099.746 1301.685  3470.156   100 a  

【问题讨论】:

  • 也可能是基础 R anyDuplicated。这个功能做了一点优化。还有一种方法适用于data.table。在向量或 data.table 的开头(顶部)出现许多重复或重复的情况下,这些在概念上将比全向量扫描更快,因为当发现重复时它们应该短路。
  • 基准测试中的第一种方法非常糟糕,可以放心地忽略。如果 DT 有很多非关键列,它们都保留在 unique(DT, ...) 中。其他的我猜都是一样的,包括DT[, uniqueN(.SD) == .N, .SDcols=key(DT)]。就个人而言,我使用慢得多的DT[, .N, by=key(DT)][N &gt; 0, .N == 0L] 来更轻松地进行诊断。

标签: r performance data.table


【解决方案1】:

识别可疑组合键是否唯一 只需测试 group_by 的 nrow() 返回 SAME nrow() 作为其输入数据帧

library(dplyr)
z <- data.frame(Repeated=sample(LETTERS[1:5], size=5, replace=TRUE),
                NOT_Repeated=sample(LETTERS[1:5], size=5, replace=FALSE))
z                                
test_unique <- z %>% group_by(Repeated) %>% summarise(Count=n_distinct(Repeated))
test_unique
nrow(z) == nrow(test_unique)

test_unique <- z %>% group_by(NOT_Repeated) %>% summarise(Count=n_distinct(NOT_Repeated))
test_unique
nrow(z) == nrow(test_unique)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-03
    • 2013-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多