SORU
1 Aralık 2010, ÇARŞAMBA


'/veri birleştirme katılmak için en hızlı yol.R Kare?

Örneğin (tabii en iyi temsil eden örnek olsa da olmasa):

N <- 1e6
d1 <- data.frame(x=sample(N,N), y1=rnorm(N))
d2 <- data.frame(x=sample(N,N), y2=rnorm(N))

Bu şimdiye kadar ne aldım

d <- merge(d1,d2)
# 7.6 sec

library(plyr)
d <- join(d1,d2)
# 2.9 sec

library(data.table)
dt1 <- data.table(d1, key="x")
dt2 <- data.table(d2, key="x")
d <- data.frame( dt1[dt2,list(x,y1,y2=dt2$y2)] )
# 4.9 sec

library(sqldf)
sqldf()
sqldf("create index ix1 on d1(x)")
sqldf("create index ix2 on d2(x)")
d <- sqldf("select * from d1 inner join d2 on d1.x=d2.x")
sqldf()
# 17.4 sec

CEVAP
1 Aralık 2010, ÇARŞAMBA


Maç bu yaklaşım ilk olarak, her anahtar değeri için ikinci bir veri çerçevesi içinde benzersiz bir anahtar var. Eğer ikinci veri çerçeve kopyalarını yeniden ve yaklaşımları aynı değildir maç Birleştir. Maç, tabii ki, çok işin olmadığı için daha hızlıdır. Özellikle hiç yinelenen anahtarlar arar. (kod sonra devam)


> DF1 = data.frame(a = c(1, 1, 2, 2), b = 1:4)
> DF2 = data.frame(b = c(1, 2, 3, 3, 4), c = letters[1:5])
> merge(DF1, DF2)
      b a c
    1 1 1 a
    2 2 1 b
    3 3 2 c
    4 3 2 d
    5 4 2 e
> DF1$c = DF2$c[match(DF1$b, DF2$b)]
> DF1$c
[1] a b c e
Levels: a b c d e
> DF1
  a b c
1 1 1 a
2 1 2 b
3 2 3 c
4 2 4 e

Bu sqldf kodu olduğunu yayınlanan soru, belki görünen dizinler edildi kullanılan iki tablo ama, aslında, onlar yerleştirilmiş tablolar hangileri üzerine önce sql seçin daha çalışır ve bu, kısmen hesapları için neden bu kadar yavaş. Sqldf fikri R oturumunda veri çerçevesi veri tabanı sqlite tabloları oluşturmaktadır. Böylece kod R bakar vasıfsız tablo adını gösteriyor her zaman ... ana sqlite veritabanı için çalışma alanı. Böylece gösterilen select deyimi sqlite ana veritabanına çalışma alanından d1 ve d2 dizinleri ile orada olanlar clobbering okur. Sonuç olarak bir dizin ile bir araya geliyor. Eğer sqlite ana veritabanı olan d1 ve d2 sürümleri kullanmak istiyorsan ana olarak onlara başvurmak gerekir.d1 ve ana.d2 ve d1 ve d2. Ayrıca, eğer sağlamaya çalıştırmak mümkün olduğunca hızlı not, basit bir katılamıyor faydalanmak dizinler üzerinde her iki tablo edebilirsiniz zaman yaratmak dizinleri. Aşağıdaki kod, bu noktaları gösteriyoruz.

Onun değerli ve hassas bir hesaplama hangi paketin en hızlı büyük bir fark yaratabilir dikkat edin. Örneğin, bir birleştirme ve aşağıda bir toplama. Sonuç ikisi için neredeyse ters olduğunu görüyoruz. En hızlı, en yavaş için gelen ilk örnek: data.tablo, plyr, ikinci örnekte ise sqldf, toplama, veri birleştirme sqldf.tablo ve plyr ilki neredeyse ters--. İlk örnekte sqldf 3x daha yavaş veri daha.masa ve ikinci yılında 200x plyr daha hızlı ve veri oranla 100 kat daha hızlı.tablo. Giriş kodu gösteriyoruz aşağıda, çıkış birleştirme ve çıkış toplamak için zamanlama için zamanlama. Onun da değerli olduğunu belirterek sqldf dayalı bir veritabanı ve bu nedenle idare nesneleri daha büyük R idare (eğer kullandığınız dbname tartışmanın sqldf) ise diğer yaklaşımlar ile sınırlıdır işleme ana bellek. Ayrıca sqlite ile sqldf resimli var ama yine de H2 ve PostgreSQL veritabanlarını destekler.


library(plyr)
library(data.table)
library(sqldf)

set.seed(123) N <- 1e5 d1 <- data.frame(x=sample(N,N), y1=rnorm(N)) d2 <- data.frame(x=sample(N,N), y2=rnorm(N))

g1 <- sample(1:1000, N, replace = TRUE) g2<- sample(1:1000, N, replace = TRUE) d <- data.frame(d1, g1, g2)

library(rbenchmark)

benchmark(replications = 1, order = "elapsed", merge = merge(d1, d2), plyr = join(d1, d2), data.table = { dt1 <- data.table(d1, key = "x") dt2 <- data.table(d2, key = "x") data.frame( dt1[dt2,list(x,y1,y2=dt2$y2)] ) }, sqldf = sqldf(c("create index ix1 on d1(x)", "select * from main.d1 join d2 using(x)")) )

set.seed(123)
N <- 1e5
g1 <- sample(1:1000, N, replace = TRUE)
g2<- sample(1:1000, N, replace = TRUE)
d <- data.frame(x=sample(N,N), y=rnorm(N), g1, g2)

benchmark(replications = 1, order = "elapsed", aggregate = aggregate(d[c("x", "y")], d[c("g1", "g2")], mean), data.table = { dt <- data.table(d, key = "g1,g2") dt[, colMeans(cbind(x, y)), by = "g1,g2"] }, plyr = ddply(d, .(g1, g2), summarise, avx = mean(x), avy=mean(y)), sqldf = sqldf(c("create index ix on d(g1, g2)", "select g1, g2, avg(x), avg(y) from main.d group by g1, g2")) )

İki kriter çağrı karşılaştırarak çıkış hesapları birleştirme:

Joining by: x
        test replications elapsed relative user.self sys.self user.child sys.child
3 data.table            1    0.34 1.000000      0.31     0.01         NA        NA
2       plyr            1    0.44 1.294118      0.39     0.02         NA        NA
1      merge            1    1.17 3.441176      1.10     0.04         NA        NA
4      sqldf            1    3.34 9.823529      3.24     0.04         NA        NA

Kriter çağrı çıktısı toplama hesapları karşılaştırarak

        test replications elapsed  relative user.self sys.self user.child sys.child
4      sqldf            1    2.81  1.000000      2.73     0.02         NA        NA
1  aggregate            1   14.89  5.298932     14.89     0.00         NA        NA
2 data.table            1  132.46 47.138790    131.70     0.08         NA        NA
3       plyr            1  212.69 75.690391    211.57     0.56         NA        NA

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • DJPixcell

    DJPixcell

    20 NİSAN 2007
  • MrRandomSong

    MrRandomSong

    29 Kasım 2009
  • PhoneArena

    PhoneArena

    7 NİSAN 2006