2017-05-19 44 views
8

Birleştirmeye çalıştığım birkaç büyük veri kümem var. Ne yapmak istediğimin bir oyuncak örneğini oluşturdum.Örnekleme ile data.table birleştirilmesi

require(data.table) 
set.seed(151) 
x <- data.table(a=1:100000) 
y <- data.table(b=letters[1:20],c=sample(LETTERS[1:4])) 
proportion <- data.table(expand.grid(a=1:100000,c=LETTERS[1:4])) 
proportion[,prop:=rgamma(4,shape = 1),by=a] 
proportion[,prop:=prop/sum(prop),by=a] 

üç tablo x, y ve proportion şunlardır: Üç tablo var. x'daki her öğe için tablosunun tüm tablolarından tablo proportion olasılıklarını kullanarak örnek almak ve bunları başka bir tabloya birleştirmek istiyorum. Ben ile geldi yöntemdir:

temp <- setkey(setkey(x[,c(k=1,.SD)],k)[y[,c(k=1,.SD)],allow.cartesian=TRUE][,k:=NULL],a,c) 
temp <- temp[setkey(proportion,a,c)][,prop:=prop/.N,by=.(a,c)] # Uniform distribution within the same 'c' column group 
chosen_pairs <- temp[,.SD[sample(.N,5,replace=FALSE,prob = prop)],by=a] 

Fakat bu bölgelerde ilk ve sonra örnek iki tabloyu çapraz katıldığında bu yöntem bellek yoğun ve yavaştır. Bu görevi verimli (hafıza ve zaman) şekilde gerçekleştirmenin bir yolu var mı?

+0

Neden olasılıkların çözümünüzün ikinci satırında yeniden hesaplanıyorsunuz? – minem

+0

@ MārtiņšMiglinieks Ben bir '(a, c)' çifti için olasılıkları normalleştiriyorum çok sayıda olabilir b ' –

+0

Lookup' .EACHI', çapraz-birleştirirken bu sadece birleştirilmiş bölüm ile ilgilenmek için izin verir işlem, memede tam birleştirme çözülmeden. – Shape

cevap

1

this sorusunda benzer bir sorunla karşılaştım. herhangi bulursa,

myFunction <- function(x, y, proportion){ 
    temp <- setkey(setkey(x[, c(k = 1, .SD)], k)[y[,c(k = 1, .SD)], 
              allow.cartesian = TRUE][, k := NULL], 
      a, c) 
    temp <- temp[setkey(proportion, a, c)][, prop := prop/.N, by = .(a, c)] 
    chosen_pairs <- temp[, sample(.I, 5, replace = FALSE, prob = prop), by = a] 
    indexes <- chosen_pairs[[2]] 
    temp[indexes] 
} 

require(rbenchmark) 
benchmark(myFunction(x, y, proportion), goreF(x, y, proportion), 
     replications = 1, 
     columns = c("test", "replications", "elapsed", "relative", 
        "user.self", "sys.self")) 
          test replications elapsed relative user.self sys.self 
2  goreF(x, y, proportion)   1 19.83 21.323  19.35  0.13 
1 myFunction(x, y, proportion)   1 0.93 1.000  0.86  0.08 

Belki de bulunabilir fazla iyileştirmeler, ben güncellenecektir:

goreF <- function(x,y,proportion){ 
    temp <- setkey(setkey(x[, c(k = 1, .SD)], k)[y[,c(k = 1, .SD)], 
            allow.cartesian = TRUE][, k := NULL], 
      a, c) 
    temp <- temp[setkey(proportion, a, c)][, prop := prop/.N, by = .(a, c)] 
    chosen_pairs <- temp[, .SD[sample(.N, 5, replace = FALSE, prob = prop)], 
        by = a] 
    chosen_pairs 
} 

Benim yaklaşım: Daha iyi karşılaştırma için fonksiyonun içine çözümünü tamamladı. İlk iki işlem çok karmaşık görünüyor, belki de kısaltılabilirler, ama hesaplama zamanlarını etkilediklerini görmediğim gibi, onları yeniden yazmadım.

Güncelleme: gruplar sadece tek bir eleman içerdiği anlamına gelir eğer başlangıçta belirtilen söz konusu işaret

olarak,, myFunction derde girebilir. Bu yüzden, bu gönderideki yorumlara dayanarak değiştirdim.

myFunction2 <- function(x, y, proportion){ 
    temp <- setkey(setkey(x[, c(k = 1, .SD)], k)[y[,c(k = 1, .SD)], 
               allow.cartesian = TRUE][, k := NULL], 
       a, c) 
    temp <- temp[setkey(proportion, a, c)][, prop := prop/.N, by = .(a, c)] 
    indexes <- temp[, .I[sample(.N, 5, replace = T, prob = prop)], by = a] 
    indexes <- indexes[[2]] 
    temp[indexes] 
} 

benchmark(myFunction(x, y, proportion), myFunction2(x, y, proportion), 
      replications = 5, 
      columns = c("test", "replications", "elapsed", "relative", 
         "user.self", "sys.self")) 

          test replications elapsed relative user.self sys.self 
1 myFunction(x, y, proportion)   5 6.61 1.064  6.23  0.36 
2 myFunction2(x, y, proportion)   5 6.21 1.000  5.71  0.26 

Marjinal hızın iyileşmesini görebiliriz.

+0

Benzer bir şey yapıyorum. Soruyu güncellemeliydim. Kullandığım adım “selected_pairs <- temp [temp [,. (B = örnek (b, 5, yerine = FALSE, prob = prop)), a = a], on = c (" a ", "b")] 'işlevi ile karşılaştırılabilir çalışır. Cevabınızı kabul edeceğim ama eğer birisi bana hafızadan tasarruf etmede yardımcı olabilirse, bu şu an uğraştığım başka bir konu. –

+0

@AGore Bu işlemde tam olarak bellek sorunlarıyla karşılaşıyor musunuz? Verileriniz ve RAM'iniz ne kadar büyük? Çünkü ben hiç koşmam. Belki bazı veri azaltma önceden yapılabilir. – minem

+0

'x' ve 'y' veri kümesi yaklaşık 5 Gb ve 2 Gb'dir. Çapraz birleştirmeler yaklaşık 12 Gb olan çıktıyı üretir. Son çıktı (örneklemenin bir sonucu olarak) yaklaşık 6 Gb'dir. 16 Gb'lik bir RAM'ım var. Veri azaltmayı nerede yapabileceğimi anlayamıyorum. –