电竞比分网-中国电竞赛事及体育赛事平台

分享

幾種加快R語言運算的方法

 育種數(shù)據(jù)分析 2021-11-18

提升R代碼運行速度并不需要很高級的優(yōu)化技術(shù), 例如代碼并行化, 使用數(shù)據(jù)庫, 使用c++等. 實際上, 通過簡單的操作, 就能夠是R的運算速度顯著的加快, 下面介紹幾種方法.

1, 向量化

R語言允許用戶進行向量化編程, 這樣速度更快.

比如我們計算100萬隨機數(shù), 計算他們的平方, 這里使用兩種方法: 第一種, for循環(huán); 第二種, 向量化

set.seed(123)
dat= rnorm(1000000)

for循環(huán)

system.time({
dd = NULL
for(i in 1:length(dat)){
dd[i] = dat[i]^2
}
})
user system elapsed
0.31 0.03 0.35

    直接在原向量上計算平方

    system.time({
    dd2 =dat^2
    })
    user system elapsed
    0 0 0
    head(dat);head(dd2)

    速度由0.3s到0.02s

    2, 預(yù)分配內(nèi)存

    R語言是動態(tài)分布內(nèi)存的, 不需要預(yù)先定義變量, 可以直接使用. 這種方法比較簡單, 但是數(shù)據(jù)量大時, 會影響速度. 所以在使用變量時, 提前聲明變量的大小, 會提升速度

    不預(yù)先分布內(nèi)存

    這個程序, 不知道dat的長度是多少, 因此是動態(tài)的內(nèi)存結(jié)構(gòu).

    N = 1e5;N

    1e+05

    system.time({
    dat =1
    for(i in 2:N){
    dat = c(dat,dat[i-1]+sample(1:2,size = 1))
    }
    })
    user system elapsed
    8.88 0.15 9.07

    預(yù)先分配內(nèi)存

    dat的長度是1e5, 因此我們可以生成這一個為0的向量, 這樣他的內(nèi)存就固定了

    N = 1e4;N
    dat = rep(0,N)

    10000

    system.time({
    dat =1
    for(i in 2:N){
    dat = c(dat,dat[i-1]+sample(1:2,size = 1))
    }
    })
    user system elapsed
    0.14 0.00 0.14

    可以看到, 時間由7.5s降到0.11s

    3, 使用apply函數(shù)代替for循環(huán)

    apply函數(shù)及其變種:

    • lapply

    • sapply

    • tapply

    如果各個迭代之間相互獨立, 那么apply函數(shù)是可以代替for循環(huán)的

    for循環(huán)

    set.seed(123)
    dat= rnorm(1000000)
    system.time({
    dd = NULL
    for(i in 1:length(dat)){
    dd[i] = dat[i]^2
    }
    })
    user system elapsed
    0.28 0.00 0.28
    square = function(x){ return(x^2)
    }
    system.time({tt = lapply(dat, FUN=square)}) user system elapsed
    1.00 0.00 1.02
    t = rep(0,length(dat))system.time({t = lapply(dat, FUN=square)}) user system elapsed
    0.62 0.03 0.66

    4, 使用matrix而不是data.table

    在矩陣運算時, 盡量轉(zhuǎn)化為matrix格式

    使用matrix

    dat = matrix(rnorm(1e4*1000),1e4,1000)dd = as.data.frame(dat)
    system.time( rowSums(dd))
    user system elapsed
    0.05 0.00 0.05

    使用data.frmae

    system.time( rowSums(dat)) user system elapsed
    0.04 0.00 0.03

      轉(zhuǎn)藏 分享 獻花(0

      0條評論

      發(fā)表

      請遵守用戶 評論公約

      類似文章 更多