在大数据帧(3.2GB)中使用sum非常慢

时间:2014-11-25 10:35:46

标签: r dataframe

我有一个超过3 GB的大数据框(2628x670316),并想在每一行使用sum函数。

数据文件看起来像这样只包含0s,1s和2s。

0 1 2 0 0 0 0 0 0 1 1 1 ...
0 1 0 0 0 0 2 2 2 2 2 2 ...
.
.
.

当我运行sum(data [1,] == 0)时,这需要很长时间。有没有更快的方法呢?

提前谢谢。

PS。我想使用sum的原因是因为我想在每一行上获得0s,1s和2s的百分比。如果有另一种方法可以做到这一点,那么这个答案也会有所帮助。

3 个答案:

答案 0 :(得分:3)

如果df是您的data.frame:

t(apply(df,1,table))*100/ncol(df)

将为每行提供0s,1s和2s的百分比。

(你避免进行比较,这可能需要很长时间......)

数据:

set.seed(13)
df<-data.frame(matrix(sample(c(0,1,2),500,T),nrow=10))

t(apply(df,1,table))*100/ncol(df)为您提供:

       0  1  2
 [1,] 34 44 22
 [2,] 38 40 22
 [3,] 28 34 38
 [4,] 26 38 36
 [5,] 36 42 22
 [6,] 30 32 38
 [7,] 42 26 32
 [8,] 30 36 34
 [9,] 36 24 40
[10,] 24 34 42

编辑感谢@akrun的评论:

如果每行都没有表示所有可能的值(0,1,2),则必须执行以下操作:

t(apply(df, 1, function(x) table(factor(x, levels=0:2))))*100/ncol(df)

答案 1 :(得分:2)

如果数据都是整数,那么将它表示为矩阵m要快得多(这在语义上也更接近于数据的实际情况 - 具有同质性的矩形数据集合类型,而不是可能不同类型的列),可能使用scan()输入。使用矩阵,列操作比行操作更快,因此使用t(m)转置它。 tabulate()函数比table()快得多,但在目前情况下稍微挑剔一点

nonZeroCounts <- apply(t(m), 2, tabulate, max(m))

更详细地说,这里是提出的解决方案

f0 <- function(df)
    t(apply(df, 1, table))

f1 <- function(m) {
    n <- t(apply(t(m), 2, tabulate, max(m)))
    ans <- cbind(ncol(m) - as.integer(rowSums(n)), n)
    colnames(ans) <- 0:max(m)
    ans
}

一些数据

nrow <- 100; ncol <- floor(nrow * 670316 / 2628)
m <- matrix(sample(0:2, nrow * ncol, TRUE), nrow=nrow)
df <- as.data.frame(m)

和基本比较

> system.time(ans0 <- f0(df))
   user  system elapsed 
  1.082   0.000   1.083 
> system.time(ans1 <- f1(m))
   user  system elapsed 
  0.052   0.000   0.052 
> identical(ans0, ans1)
[1] TRUE

nrow=1000

> system.time(ans1 <- f1(m))
   user  system elapsed 
  6.521   1.461   7.984 
> system.time(ans0 <- f0(df))   ## argh, boring, stop after 1.5 minutes!
  C-c C-c
Timing stopped at: 93.608 2.752 96.325 

答案 2 :(得分:0)

尝试rowSums,也许它更快

test<-data.frame(V1=c(1,1,1,1), V2=c(2,2,2,0)) 
rowSums(test)

我怀疑你能获得比香草和更快的和函数。

获得总和的另一种方法是臭名昭着的apply函数族

apply(test, 1, sum)

一些测试和rowSums是否相当快

set.seed(13)
df<-data.frame(matrix(sample(c(0,1,2),500000000,T),nrow=2000))
system.time(rowSums(df))

system.time(rowSums(df))
   user  system elapsed 
   8.00    0.68    8.69

apply

system.time(apply(df, 1, sum))


   user  system elapsed 
  81.67    5.99   87.96 
相关问题