当前位置: 首页 > 知识库问答 >
问题:

如何有效地计算数据的唯一(数字)列向量。桌子

巫朝明
2023-03-14
foo <- data.table(x = 1:5/sum(1:5),
                  y = (-4):0/sum((-4):0),
                 z1 = 2:6/sum(2:6),
                 z2 = 2:6/sum(2:6))

假设我有foo数据表(如上所述):

            x   y   z1   z2
1: 0.06666667 0.4 0.10 0.10
2: 0.13333333 0.3 0.15 0.15
3: 0.20000000 0.2 0.20 0.20
4: 0.26666667 0.1 0.25 0.25
5: 0.33333333 0.0 0.30 0.30

如何有效地计算唯一列?在这种情况下,只有3个。

请假设一般情况下:

  1. foo始终是数据表而不是矩阵;尽管列始终是数字

是否可以在不制作额外数据副本的情况下执行此操作?

我目前的方法是使用粘贴对列应用,为每列获取一个值,然后执行长度(唯一() 在结果上。。。

数据有什么魔力吗。表::transpose()数据。表::uniqueN,还有其他朋友?


共有3个答案

庄新翰
2023-03-14

另一种方法可能更快,如果你期望大量重复:

n_unique_cols <- function(foo) {
  K <- seq_along(foo)
  for (j in seq_along(foo)) {
    if (j %in% K) {
      foo_j <- .subset2(foo, j)
      for (k in K) {
        if (j < k) {
          foo_k <- .subset2(foo, k)
          if (foo_j[1] == foo_k[1] && identical(foo_j, foo_k)) {
            K <- K[K != k]
          }
          rm(foo_k)
        }
      }
    }
  }
  length(K)
}

时间:

library(data.table)
create_foo <- function(row, col) {
  foo <- data.table(x = rnorm(row), 
                    y = seq_len(row) - 2L)

  set.seed(1)
  for (k in seq_len(col %/% 2L)) {
    foo[, (paste0('x', k)) := x + sample(-4:4, size = 1)]
    foo[, (paste0('y', k)) := y + sample(-2:2, size = 1)]
  }
  foo
}

library(bench)
res <- 
  press(rows = c(1e5, 1e6, 1e7), 
        cols = c(10, 50, 100), 
        {

          foorc <- create_foo(rows, cols)
          bench::mark(n_unique_cols(foorc), 
                      length(unique(as.list(foorc))))
        })
plot(res)

此函数的数据消耗量是其唯一性的两倍()

党权
2023-03-14

转置并检查是否存在非重复项

ncol( foo[ , which( !duplicated( t( foo ) ) ), with = FALSE ])

3
姚韬
2023-03-14

另一种可能性:

length(unique(as.list(foo)))

它给出了预期的结果:

> length(unique(as.list(foo)))
[1] 3

注意:必须使用length(unique()),因为uniqueN()将返回错误。

根据@Ryan的评论,你也可以这样做:

length(unique.default(foo))

关于速度,这两种方法是可比的(当在5M行的更大数据集上测量时):

> fooLarge <- foo[rep(1:nrow(foo),1e6)]
> microbenchmark(length(unique.default(fooLarge)), length(unique(as.list(fooLarge))))
Unit: milliseconds
                              expr     min       lq     mean   median       uq       max neval cld
  length(unique.default(fooLarge)) 94.0433 94.56920 95.24076 95.01492 95.67131 103.15433   100   a
 length(unique(as.list(fooLarge))) 94.0254 94.68187 95.17648 95.02672 95.49857  99.19411   100   a

如果只保留唯一的列,可以使用:

# option 1
cols <- !duplicated(as.list(foo))
foo[, ..cols]

# option 2 (doesn't retain the column names)
as.data.table(unique.default(foo))

其中给出(显示输出选项1):

            x   y   z1
1: 0.06666667 0.4 0.10
2: 0.13333333 0.3 0.15
3: 0.20000000 0.2 0.20
4: 0.26666667 0.1 0.25
5: 0.33333333 0.0 0.30
 类似资料:
  • 问题内容: 如果我有三列: 我想计算一下表格中有多少唯一的电子邮件,我该怎么做? 如下语句: 给我总数。 我试过了 但这似乎并没有给我期望的数字。 问题答案: 采用 提供唯一的电子邮件ID,然后简单地对其进行计数。

  • 下面有一段代码,它创建了数据框中每列中缺失值的汇总表。我希望我可以构建一个类似的表来计算唯一的值,但是DataFrame没有唯一的()方法,只有每一列是独立的。 (资料来源:https://stackoverflow.com/a/39734251/7044473) 如何为唯一值实现相同的功能?

  • 我正在尝试将嵌套列表结构转换为DataFrame。该列表类似于以下内容(它是来自解析的JSON的序列化数据,使用httr包读取)。 编辑:我最初的示例数据太简单了。实际数据是不完整的,这意味着并非每个对象都存在所有变量,并且一些列表元素是空的。我编辑了数据来反映这一点。

  • 问题内容: 假设我有以下由四行三列组成的2D numpy数组: 生成包含所有列之和的一维数组的有效方法是什么(如)?无需遍历所有列就能做到这一点吗? 问题答案: 请查看的文档,特别注意该参数。汇总列: 或者,总结行: 其他聚合函数一样,并且,例如,也采取了参数。 从暂定NumPy的教程: 许多一元运算(例如计算数组中所有元素的总和)都作为该类的方法实现。默认情况下,这些操作适用于数组,就好像它是数

  • 问题内容: 计算对象的键/属性数量的最快方法是什么?是否可以在不迭代对象的情况下执行此操作?即不做 (Firefox确实提供了一个魔术属性,但是在版本4的某个位置将其删除。) 问题答案: 要在任何与 ES5兼容的环境 (例如Node,Chrome,IE 9+,Firefox 4+或Safari 5+)中执行此操作: 浏览器兼容性 Object.keys文档(包括可以添加到非ES5浏览器的方法)

  • 我解决了以下提供的协同问题。 给出了一个整数M和一个由N个非负整数组成的非空数组A。数组A中的所有整数都小于或等于M。 一对整数(P, Q),使得0≤P≤Q 例如,考虑整数M=6和数组A,这样: 目标是计算不同切片的数量。 编写函数: 类解决方案{公共int解决方案(int M,int[]A);} 如果给定一个整数M和一个由N个整数组成的非空数组a,则返回不同的片数。 如果不同切片的数量大于1,0