首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何防止rbind()在dataframe变大时变得非常慢?

如何防止rbind()在dataframe变大时变得非常慢?
EN

Stack Overflow用户
提问于 2013-02-05 03:23:00
回答 2查看 12.4K关注 0票数 11

我有一个只有1行的数据帧。为此,我开始使用rbind添加行

代码语言:javascript
复制
df #mydataframe with only one row
for (i in 1:20000)
{
    df<- rbind(df, newrow)

}

随着我的成长,这会变得非常缓慢。为什么会这样呢?我怎样才能让这种类型的代码更快呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-02-05 03:32:39

您处于2nd circle of hell中,即未能预先分配数据结构。

以这种方式增加对象在R中是一件非常非常糟糕的事情。可以预先分配或插入:

代码语言:javascript
复制
df <- data.frame(x = rep(NA,20000),y = rep(NA,20000))

或者重新构造代码以避免这种增量添加行的行为。正如在我引用的链接中所讨论的,速度慢的原因是每次添加一行时,R都需要找到一个新的连续的内存块来容纳数据帧。有很多抄袭。

票数 21
EN

Stack Overflow用户

发布于 2013-02-05 06:22:40

我试过一个例子。无论它的价值是什么,它都同意用户的断言,即在数据框中插入行也非常慢。我不太明白发生了什么,因为我认为分配问题会胜过复制的速度。任何人都可以复制这一点,或者解释为什么下面的结果(rbind <追加<插入)通常是正确的,或者解释为什么这不是一个有代表性的例子(例如,数据帧太小)?

编辑:第一次我忘记将hell2fun中的对象初始化为数据帧,所以代码进行的是矩阵运算,而不是数据帧操作,后者要快得多。如果有机会,我会将比较扩展到数据帧与矩阵。不过,第一段中的定性断言仍然成立。

代码语言:javascript
复制
N <- 1000
set.seed(101)
r <- matrix(runif(2*N),ncol=2)

## second circle of hell
hell2fun <- function() {
    df <- as.data.frame(rbind(r[1,])) ## initialize
    for (i in 2:N) {
        df <- rbind(df,r[i,])
    }
}

insertfun <- function() {
    df <- data.frame(x=rep(NA,N),y=rep(NA,N))
    for (i in 1:N) {
        df[i,] <- r[i,]
    }
}

rsplit <- as.list(as.data.frame(t(r)))
rbindfun <-  function() {
    do.call(rbind,rsplit)
}

library(rbenchmark)
benchmark(hell2fun(),insertfun(),rbindfun())

##          test replications elapsed relative user.self 
## 1  hell2fun()          100  32.439  484.164    31.778 
## 2 insertfun()          100  45.486  678.896    42.978 
## 3  rbindfun()          100   0.067    1.000     0.076 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14693956

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档