performance - 为什么在数据帧上运行 "unique"比 R 中的矩阵更快?

标签 performance r matrix dataframe data.table

我已经开始相信数据框与矩阵相比没有优势,除了符号方便。但是,我在运行 unique 时注意到了这种奇怪现象。在矩阵和数据帧上:它似乎在数据帧上运行得更快。

a   = matrix(sample(2,10^6,replace = TRUE), ncol = 10)
b   = as.data.frame(a)

system.time({
    u1 = unique(a)
})
 user  system elapsed
1.840   0.000   1.846


system.time({
    u2 = unique(b)
})
 user  system elapsed
0.380   0.000   0.379

随着行数的增加,时序结果的差异甚至更大。所以,这个问题有两个部分。
  • 为什么这对于矩阵来说更慢?转换为数据框似乎更快,运行unique ,然后转换回来。
  • 有什么理由不直接包装uniquemyUnique ,第 1 部分中的转换是什么?


  • 注 1. 鉴于矩阵是原子的,似乎 unique矩阵应该更快,而不是更慢。能够迭代固定大小的连续内存块通常应该比运行单独的链表 block 更快(我假设这就是数据帧的实现方式......)。

    注 2. 正如 data.table 的表现所证明的那样, 运行 unique在数据框或矩阵上是一个相对糟糕的主意 - 请参阅 Matthew Dowle 的答案和相对时间的评论。我已经将很多对象迁移到数据表中,而这种性能是这样做的另一个原因。因此,尽管应该很好地为用户提供采用数据表的服务,但出于教学/社区的原因,我将暂时保留这个问题,即为什么矩阵对象需要更长的时间。下面的答案解决了时间都去哪儿了,以及我们如何才能获得更好的性能(即数据表)。答案近在咫尺 - 代码可通过 unique.data.frame 找到和 unique.matrix . :) 对它在做什么的英文解释以及为什么缺少这一切。

    最佳答案

  • 在这个实现中,unique.matrixunique.array 相同
    > identical(unique.array, unique.matrix)[1] TRUE
  • unique.array必须处理多维数组,这需要额外的处理来“折叠”在二维情况下不需要的额外维度(对 paste() 的额外调用)。代码的关键部分是:
    collapse <- (ndim > 1L) && (prod(dx[-MARGIN]) > 1L)temp <- if (collapse) apply(x, MARGIN, function(x) paste(x, collapse = "\r"))
  • unique.data.frame针对 2D 情况进行了优化,unique.matrix不是。正如您所建议的那样,它可能不在当前的实现中。

  • 请注意,在存在多个维度的所有情况下(unique.{array,matrix,data.table}),它是比较唯一性的字符串表示形式。对于浮点数,这意味着 15 个十进制数字,所以
    NROW(unique(a <- matrix(rep(c(1, 1+4e-15), 2), nrow = 2)))
    1尽管
    NROW(unique(a <- matrix(rep(c(1, 1+5e-15), 2), nrow = 2)))

    NROW(unique(a <- matrix(rep(c(1, 1+4e-15), 1), nrow = 2)))
    都是2 .你确定unique是你想要的吗?

    关于performance - 为什么在数据帧上运行 "unique"比 R 中的矩阵更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7809570/

    相关文章:

    返回 dplyr mutate 中的多列

    java - Sandy-Bridge CPU 优化?

    javascript - 用于单页 Web 应用程序的 New Relic 真实用户监控

    r - 在 Shiny [R] 中上传 CSV 文件后执行操作

    r - 通过存储在向量中的数字索引从数据表中提取列

    c - 寻找高效的聚类算法

    c - C 中两个矩阵的和与积(带函数)

    matrix - 在 Julia 中构造随机正交矩阵序列

    css - 实际表比。分区表

    sql - 在我的表触发器中记录更改的更有效方法