2017-05-19 10 views
8

मेरे पास कुछ बड़े डेटा-सेट हैं जिन्हें मैं गठबंधन करने की कोशिश कर रहा हूं। मैंने एक खिलौना उदाहरण बनाया है जो मैं करना चाहता हूं।नमूनाकरण द्वारा डेटा.table में शामिल हों

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] 

तीन तालिकाओं हैं x, y, और proportion: मैं तीन टेबल है। 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)] # Uniform distribution within the same 'c' column group 
chosen_pairs <- temp[,.SD[sample(.N,5,replace=FALSE,prob = prop)],by=a] 

लेकिन के रूप में यह पहले और उसके बाद नमूना पार मिलती है दो तालिका से इस विधि स्मृति गहन और धीमी है। क्या इस कार्य को एक कुशल (स्मृति और समय) तरीके से करने का कोई तरीका है?

+0

आप अपने समाधान की दूसरी पंक्ति में संभावनाओं का पुनर्मूल्यांकन क्यों कर रहे हैं? – minem

+0

@ मार्टिविस्मिग्लिनिक्स मैं संभावनाओं को सामान्यीकृत कर रहा हूं क्योंकि किसी दिए गए '(ए, सी)' जोड़ी के लिए कई 'बी' –

+0

लुकअप' ईएसीआईआई 'हो सकता है, जब क्रॉस-इनिंग करने से आप प्रत्येक में शामिल हिस्से से निपट सकते हैं मेम में पूर्ण शामिल होने के बिना ऑपरेशन, ऑपरेशन। – Shape

उत्तर

1

मुझे this प्रश्न में कुछ हद तक समान समस्या का सामना करना पड़ा। ,

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 

शायद वहाँ पाया जा सकता है और अधिक सुधार, मैं अद्यतन करेगा, यदि कोई हो पाया:

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 
} 

मेरे दृष्टिकोण: मैं बेहतर की तुलना के लिए समारोह में अपने समाधान लपेटा। पहले दो ऑपरेशन बहुत जटिल लगते हैं, शायद उन्हें छोटा किया जा सकता है, लेकिन, जैसा कि मैंने नहीं देखा कि वे गणना समय को प्रभावित करते हैं, मैंने उन्हें फिर से लिखा नहीं है।

अद्यतन:

के रूप में सवाल कि मैंने शुरू में बताया गया में बताया, तो आप myFunction के साथ मुसीबत में मिल सकता है, यदि आपका समूह केवल एक ही तत्व शामिल हैं। इसलिए मैंने उस पोस्ट की टिप्पणियों के आधार पर इसे संशोधित किया।

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 

हम मामूली गति सुधार देख सकते हैं।

+0

मैं कुछ ऐसा ही कर रहा था। मुझे सवाल अपडेट करना चाहिए था। जिस चरण का मैं उपयोग कर रहा था वह है 'select_pairs <- temp [temp [,। (बी = नमूना (बी, 5, प्रतिस्थापित = गलत, प्रो = प्रो)), द्वारा = ए], = = ("ए" पर, "बी")] 'जो आपके कार्य के तुलनीय है। मैं आपका जवाब स्वीकार करूंगा लेकिन अगर कोई मुझे स्मृति बचाने में मदद कर सकता है क्योंकि यह एक और मुद्दा है जिसे मैं अभी सामना कर रहा हूं। –

+0

@AGore क्या आप इस ऑपरेशन में बिल्कुल स्मृति समस्याओं में भाग लेते हैं? आपका डेटा और आपकी रैम कितनी बड़ी है? क्योंकि मैं किसी में भाग नहीं लेता हूं। हो सकता है कि पहले कुछ डेटा कटौती की जा सके। – minem

+0

डेटासेट 'x' और' y' लगभग 5 जीबी और 2 जीबी रेस हैं। क्रॉस में शामिल होता है जो उत्पादन लगभग 12 जीबी है। अंतिम आउटपुट (नमूनाकरण के परिणामस्वरूप) लगभग 6 जीबी है। मेरे पास 16 जीबी की रैम है। मैं यह नहीं समझ सकता कि मैं डेटा कमी कहां कर सकता हूं। –

संबंधित मुद्दे