20

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

そのようなプロセスをスピードアップする方法はありますか?たとえば、私が行っている方法は非常に遅く、これにはより速いアプローチがありますか?ありがとう。

4

3 に答える 3

31

dfを行列に変換してみてください。

df <- data.frame(a=rnorm(1000),b=rnorm(1000))
m <- as.matrix(df)
m[m<0] <- 0
df <- as.data.frame(m)
于 2012-10-11T09:15:26.087 に答える
23

m元のアプローチと現在の回答の両方で、作成時に(またはdf)と同じサイズのオブジェクトが作成されます(マトリックスアプローチは、比較してm<0内部コピーが少ないため、より高速です)[<-[<-.data.frame

lapplyとを使用できますreplace。そうすれば、ベクトルまたは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未満のキー値を参照で置き換えることができます。

于 2012-10-17T00:46:33.140 に答える
0

別の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

.j引数で使用される記号iは繰り返され、引数の列に置き換えられjます。

于 2019-01-29T11:04:36.507 に答える