【问题标题】:Fast replacing values in dataframe in RR中数据框中的快速替换值
【发布时间】:2012-10-01 21:41:52
【问题描述】:

我有一个 150,000 行的数据框,其中 2,000 列包含值,其中一些是负数。 我将这些负值替换为 0,但这样做非常慢(约 60 分钟或更长时间)。

df[df < 0] = 0

df[,1441:1453] 的样子(所有列/值都是数字):

  V1441 V1442 V1443 V1444 V1445 V1446 V1447 V1448 V1449 V1450 V1451 V1452 V1453
1     3     1     0     4     4    -2     0     3    12     5    17    34    27
2     0     1     0     7     0     0     0     1     0     0     0     0     0
3     0     2     0     1     2     3     6     1     2     1    -6     3     1
4     1     2     3     6     1     2     1    -6     3     1    -4     1     0
5     1     2     1    -6     3     1    -4     1     0     0     1     0     0
6     1     0     0     1     0     0     0     0     0     0     1     2     2

有没有办法加快这样的过程,例如我这样做的方式非常慢,有更快的方法吗? 谢谢。

【问题讨论】:

  • 150,000 行 x 2000 列:这是正确的
  • 请问show us 您的数据是什么样的?所有列都是数字吗?

标签: r replace dataframe


【解决方案1】:

尝试将您的 df 转换为矩阵。

df <- data.frame(a=rnorm(1000),b=rnorm(1000))
m <- as.matrix(df)
m[m<0] <- 0
df <- as.data.frame(m)

【讨论】:

  • 真的真的更快!
【解决方案2】:

在创建m&lt;0 时,您的原始方法和当前答案都创建了与m(或df)大小相同的对象(矩阵方法更快,因为与[&lt;- 相比,内部复制更少[&lt;-.data.frame

你可以使用lapplyreplace,那么你每次只看一个向量或者length (nrow(df)) 而不是抄袭那么多

df <- as.data.frame(lapply(df, function(x){replace(x, x <0,0)})

上面的代码应该是相当高效的。

如果您使用data.table,则消除了data.frame 方法的大部分内存(和)时间效率低下。它非常适合像您这样的大数据情况。

library(data.table)
# this really shouldn't be 
DT <- lapply(df, function(x){replace(x, x <0,0)})
# change to data.table
setattr(DT, 'class', c('data.table','data.frame'))
# or 
# DT <- as.data.table(df, function(x){replace(x, x <0,0)})

您可以在所有列上设置键,然后通过引用替换小于 0 的键值

【讨论】:

    【解决方案3】:

    另一个 data.table 答案,可能更快,而且绝对应该消耗更少的内存。

    library(data.table)
    set.seed(108)
    d = data.table(a=rnorm(1000),b=rnorm(1000))
    set.colwise = function(x, i, j, value) {
      replace_dot_j = function(e, j) {
        if (is.symbol(e) && identical(e, as.symbol(".j"))) return(j)
        if (is.call(e)) {
          if (e[[1L]] == ".j") e[[1L]] = j
          for (i in seq_along(e)[-1L]) if (!is.null(e[[i]])) e[[i]] = replace_dot_j(e[[i]], j)
        }
        e
      }
      for (jj in j) eval(substitute(
        set(x, .i, .j, value),
        list(
          .i=replace_dot_j(substitute(i), jj),
          .j=jj
        )
      ))
      invisible(x)
    }
    d
    set.colwise(d, i = which(d[[.j]] < 0), j = c("a","b"), value = 0)
    d
    

    i 参数中使用的.j 符号被迭代并替换为来自j 参数的列。

    【讨论】:

      猜你喜欢
      • 2014-12-15
      • 1970-01-01
      • 2016-02-10
      • 2022-01-14
      • 1970-01-01
      • 2011-03-25
      • 2018-05-04
      • 1970-01-01
      • 2015-07-15
      相关资源
      最近更新 更多