Plyr neden bu kadar yavaş?
Yanlış plyr kullanıyorum sanırım. Lütfen eğer bu değilse söyle bana birisi 'verimli' kod plyr?
require(plyr)
plyr <- function(dd) ddply(dd, .(price), summarise, ss=sum(volume))
Birkaç büyük toplama bir sorunum var ve biraz zaman alıyor bunların her biri olduğunu fark ettim. küçük bir durum var: Sorunları çözmek için çalışırken, R. çeşitli toplama işlemleri performansı ile ilgilenmeye başladım
Birkaç toplama yöntemleri test ettim ve bütün gün kendimi beklerken buldu.
Nihayet sonuçlar geldi, plyr yöntemi ve beni ölü bir şeyi yanlış yaptım o yüzden diğerleri arasında büyük bir boşluk keşfetti.
(Oradayken yeni dataframe paketi kontrol dışarı dedim) aşağıdaki kodu çalıştırdım:
require(plyr)
require(data.table)
require(dataframe)
require(rbenchmark)
require(xts)
plyr <- function(dd) ddply(dd, .(price), summarise, ss=sum(volume))
t.apply <- function(dd) unlist(tapply(dd$volume, dd$price, sum))
t.apply.x <- function(dd) unlist(tapply(dd[,2], dd[,1], sum))
l.apply <- function(dd) unlist(lapply(split(dd$volume, dd$price), sum))
l.apply.x <- function(dd) unlist(lapply(split(dd[,2], dd[,1]), sum))
b.y <- function(dd) unlist(by(dd$volume, dd$price, sum))
b.y.x <- function(dd) unlist(by(dd[,2], dd[,1], sum))
agg <- function(dd) aggregate(dd$volume, list(dd$price), sum)
agg.x <- function(dd) aggregate(dd[,2], list(dd[,1]), sum)
dtd <- function(dd) dd[, sum(volume), by=(price)]
obs <- c(5e1, 5e2, 5e3, 5e4, 5e5, 5e6, 5e6, 5e7, 5e8)
timS <- timeBasedSeq('20110101 083000/20120101 083000')
bmkRL <- list(NULL)
for (i in 1:5){
tt <- timS[1:obs[i]]
for (j in 1:8){
pxl <- seq(0.9, 1.1, by= (1.1 - 0.9)/floor(obs[i]/(11-j)))
px <- sample(pxl, length(tt), replace=TRUE)
vol <- rnorm(length(tt), 1000, 100)
d.df <- base::data.frame(time=tt, price=px, volume=vol)
d.dfp <- dataframe::data.frame(time=tt, price=px, volume=vol)
d.matrix <- as.matrix(d.df[,-1])
d.dt <- data.table(d.df)
listLabel <- paste('i=',i, 'j=',j)
bmkRL[[listLabel]] <- benchmark(plyr(d.df), plyr(d.dfp), t.apply(d.df),
t.apply(d.dfp), t.apply.x(d.matrix),
l.apply(d.df), l.apply(d.dfp), l.apply.x(d.matrix),
b.y(d.df), b.y(d.dfp), b.y.x(d.matrix), agg(d.df),
agg(d.dfp), agg.x(d.matrix), dtd(d.dt),
columns =c('test', 'elapsed', 'relative'),
replications = 10,
order = 'elapsed')
}
}
Test check - up için ama çok uzun sürdü 5e8, - plyr nedeniyle çoğunlukla gerekiyordu. Bu 5e5 final masasına sorunu gösterir:
$`i= 5 j= 8`
test elapsed relative
15 dtd(d.dt) 4.156 1.000000
6 l.apply(d.df) 15.687 3.774543
7 l.apply(d.dfp) 16.066 3.865736
8 l.apply.x(d.matrix) 16.659 4.008422
4 t.apply(d.dfp) 21.387 5.146054
3 t.apply(d.df) 21.488 5.170356
5 t.apply.x(d.matrix) 22.014 5.296920
13 agg(d.dfp) 32.254 7.760828
14 agg.x(d.matrix) 32.435 7.804379
12 agg(d.df) 32.593 7.842397
10 b.y(d.dfp) 98.006 23.581809
11 b.y.x(d.matrix) 98.134 23.612608
9 b.y(d.df) 98.337 23.661453
1 plyr(d.df) 9384.135 2257.972810
2 plyr(d.dfp) 9384.448 2258.048123
Bu doğru mu? Neden plyr 2250x data.table
daha yavaştır? Ve neden yeni bir veri çerçevesi paketi kullanarak bir şey değişmedi mi?
Oturum bilgi:
> sessionInfo()
R version 2.15.1 (2012-06-22)
Platform: x86_64-apple-darwin9.8.0/x86_64 (64-bit)
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] xts_0.8-6 zoo_1.7-7 rbenchmark_0.3 dataframe_2.5 data.table_1.8.1 plyr_1.7.1
loaded via a namespace (and not attached):
[1] grid_2.15.1 lattice_0.20-6 tools_2.15.1
CEVAP
Nedenbu kadar yavaş değil mi? Biraz araştırma posta grup Yorum dan gönderme yer alır. 2011 nerede @hadley, paket yazar states
Bu ddply her zaman veri ile çalışan bir dezavantajı Kare. Eğer özetlemek yerine kullanırsanız biraz daha hızlı olacak veri.Kare (veri.çerçeve çok yavaş) ama hala düşünüyorum bu ddply bu temel sınırlamayı aşmak hakkında yaklaşım.
Olmak içinverimlikod plyr da bilmiyordum. Param test bir grup ve tezgah işaretleme sonra daha iyisini yapabiliriz gibi görünüyor.
Senin emrine summarize()
sadece bir yardımcı işlevi, saf ve basit. Zaten basit bir şey ile yardımcı olmadığı için kendi sum fonksiyonu ile değiştirebilirsiniz .data
.(price)
tartışmalar daha açık hale getirilebilir. Sonucudur
ddply( dd[, 2:3], ~price, function(x) sum( x$volume ) )
summarize
güzel görünebilir, ama bu sadece basit bir işlev çağrısı daha hızlı değil. Sense; sadece summarize
code karşı bizim küçük işlev gösteriyor. Revize formülü ile kriterler çalışan göze çarpan bir kazanç sağlar. Yanlış plyr kullandın demek değil, sen değil, sadece verimli değil, diğer seçenekler kadar hızlı yapar ile yapabileceğin bir şey yok.
Benim görüşüme göre optimize fonksiyonu hala net değil ve zihinsel olarak hala gülünç yavaş ile birlikte ayrıştırıldı olarak veri ile karşılaştırıldığında kokuyor.tablo ( 60'lık bir artışı bile ).
Aynı thread, plyr yavaşlık ile ilgili olarak, plyr2 bir proje bahsediliyor yukarıda. Soruya özgün yanıt zamanından beri plyr yazar plyr halefi olarak dplyr
yayımladı. Her ikisi de plyr ve dplyr olan fatura olarak veri işleme araçları ve sizin için belirlediği birincil ilgi toplama olabilir hala ilgilenir senin deney sonuçları yeni paket için karşılaştırma gibi bir futbolcu arka uç performansı arttırmak.
plyr_Original <- function(dd) ddply( dd, .(price), summarise, ss=sum(volume))
plyr_Optimized <- function(dd) ddply( dd[, 2:3], ~price, function(x) sum( x$volume ) )
dplyr <- function(dd) dd %.% group_by(price) %.% summarize( sum(volume) )
data_table <- function(dd) dd[, sum(volume), keyby=price]
dataframe
paket matris işlevi sürümleri ile birlikte testlerinin BOZUK ve daha sonra kaldırıldı.
İşte i=5, j=8
kıyaslama sonuçları:
$`obs= 500,000 unique prices= 158,286 reps= 5`
test elapsed relative
9 data_table(d.dt) 0.074 1.000
4 dplyr(d.dt) 0.133 1.797
3 dplyr(d.df) 1.832 24.757
6 l.apply(d.df) 5.049 68.230
5 t.apply(d.df) 8.078 109.162
8 agg(d.df) 11.822 159.757
7 b.y(d.df) 48.569 656.338
2 plyr_Optimized(d.df) 148.030 2000.405
1 plyr_Original(d.df) 401.890 5430.946
Hayır optimize biraz yardım ettiğine eminim. d.df
fonksiyonları bir göz atın; sadece rekabet edemez.
Veri yavaşlık biraz perspektif için.çerçeve yapısı burada data_table ve dplyr büyük bir test veri kümesi kullanarak toplama zamanları (i=8,j=8
) mikro-kriterler vardır.
$`obs= 50,000,000 unique prices= 15,836,476 reps= 5`
Unit: seconds
expr min lq median uq max neval
data_table(d.dt) 1.190 1.193 1.198 1.460 1.574 10
dplyr(d.dt) 2.346 2.434 2.542 2.942 9.856 10
dplyr(d.df) 66.238 66.688 67.436 69.226 86.641 10
Verileri.karedirhalatoz toprak içinde bıraktı. Sadece bu değil, ama burada geçen bir sistem.zaman test verileri ile veri yapıları doldurmak için:
`d.df` (data.frame) 3.181 seconds.
`d.dt` (data.table) 0.418 seconds.
Veri oluşturma ve toplama.çerçeve verileri daha yavaştır.tablo.
Veri ile çalışmak.çerçeveRkriterler gösterisi olarak yavaş bazı alternatifler daha ama R fonksiyonları darbe inşa sudan plyr. Hatta verileri yönetmek.eklentiler üzerine inşa artırır dplyr, maksimum hız vermez gibi; burada veri olarak çerçeve.tablodaha hızlıoluşturma ve toplama hem deveveri.tablo veri üzerine/ile çalışırken ne yapar.Kare.
Sonunda...
Plyr çünkü yavaşbirlikte çalışır ve veri yönetir.manipülasyon çerçeve.
[punt:: özgün soru yorum.
## R version 3.0.2 (2013-09-25)
## Platform: x86_64-pc-linux-gnu (64-bit)
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] microbenchmark_1.3-0 rbenchmark_1.0.0 xts_0.9-7
## [4] zoo_1.7-11 data.table_1.9.2 dplyr_0.1.2
## [7] plyr_1.8.1 knitr_1.5.22
##
## loaded via a namespace (and not attached):
## [1] assertthat_0.1 evaluate_0.5.2 formatR_0.10.4 grid_3.0.2
## [5] lattice_0.20-27 Rcpp_0.11.0 reshape2_1.2.2 stringr_0.6.2
## [9] tools_3.0.2
Neden bu F# bu kadar yavaş?kod...
Neden stdout baskı bu kadar yavaş? Hız...
Neden dili bu kadar yavaş?...
Neden SpringSource Tool Suite (STS) bu...
Neden RSpec Raylar altında bu kadar ya...