2013-09-26 11 views
9

में मैं आदेश parLapply() उपयोग करने के लिए समानांतर में प्रत्येक विभाजन पर एक समारोह कॉल करने के लिए में split() के साथ एक डेटा फ्रेम विभाजन कर रहा हूँ। डेटा फ्रेम में 1.3 मिलियन पंक्तियां और 20 कॉल हैं। मैं चरित्र प्रकार दोनों, दो स्तंभों द्वारा विभाजन/विभाजन कर रहा हूं। ऐसा लगता है कि ~ 47 के अद्वितीय आईडी और ~ 12 के अद्वितीय कोड हैं, लेकिन आईडी और कोड की प्रत्येक जोड़ी मेल नहीं खाती है। विभाजन की परिणामी संख्या ~ 250K है। इस प्रकारफास्ट विकल्प विभाजित करने के लिए आर

system.time(pop_part <- split(pop, list(pop$ID, pop$code))) 

विभाजन तो parLapply() में खिलाया किया जाएगा:: यहाँ split() लाइन है

cl <- makeCluster(detectCores()) 
system.time(par_pop <- parLapply(cl, pop_part, func)) 
stopCluster(cl) 

मैं split() कोड अकेले गए लगभग एक घंटे चलाने के लिए और यह पूरा नहीं करता है। मैं अकेले आईडी द्वारा विभाजित कर सकता हूं, जो ~ 10 मिनट लेता है। इसके अतिरिक्त, आर स्टूडियो और वर्कर थ्रेड ~ 6 जीबी रैम का उपभोग कर रहे हैं।

कारण मैं जानता हूँ कि विभाजन के परिणामस्वरूप संख्या मैं Pentaho डेटा एकीकरण (PDI) कि (पूरे कार्यक्रम ही नहीं, "विभाजन" कोड के लिए) 30 सेकंड में चलाता है में बराबर कोड है। मैं आर के साथ उस तरह के प्रदर्शन की उम्मीद नहीं कर रहा हूं, लेकिन ऐसा कुछ जो शायद 10-15 मिनट में सबसे खराब मामला पूरा करता है।

मुख्य प्रश्न: वहाँ विभाजित करने के लिए एक बेहतर विकल्प है? मैंने को .parallel = TRUE के साथ भी आजमाया है, लेकिन यह एक घंटे से भी अधिक समय तक चला और कभी पूरा नहीं हुआ।

उत्तर

9

में pop

idx <- split(seq_len(nrow(pop)), list(pop$ID, pop$code)) 

स्प्लिट स्प्लिट अनुक्रमित, धीमी गति से नहीं है जैसे,

> system.time(split(seq_len(1300000), sample(250000, 1300000, TRUE))) 
    user system elapsed 
    1.056 0.000 1.058 

इसलिए यदि आपकी है मैं वहाँ है कि चीजें धीमा अपने डेटा के कुछ पहलू है, लगता है जैसे, ID और code, कई स्तरों और इसलिए उनका पूरा बातचीत के बजाय अपने डेटा सेट में प्रदर्शित होने के स्तर संयोजनों के साथ दोनों कारक हैं गणना कर रहे हैं

> length(split(1:10, list(factor(1:10), factor(10:1)))) 
[1] 100 
> length(split(1:10, paste(letters[1:10], letters[1:10], sep="-"))) 
[1] 10 

या शायद आप स्मृति से बाहर चला रहे हैं।

के बजायका उपयोग करें यदि आप गैर-विंडोज मशीन पर प्रक्रियाओं का उपयोग कर रहे हैं (जो मुझे लगता है कि आप detectCores() के लिए पूछते हैं)।

par_pop <- mclapply(idx, function(i, pop, fun) fun(pop[i,]), pop, func) 

सैद्धांतिक रूप से यह लगता है कि आप वास्तव में (प्रोसेसर पर एक vectorized गणना वितरित) के बजाय mclapply (अपने डेटा फ्रेम में अलग-अलग पंक्तियों पर पुनरावृति) pvec के लिए लक्ष्य कर रहे हैं।

इसके अलावा, और वास्तव में प्रारंभिक कदम के रूप में, func में बोतल गर्दन की पहचान करने पर विचार करें; डेटा बड़े लेकिन वह बड़ा तो शायद समानांतर मूल्यांकन की जरूरत नहीं है नहीं है - हो सकता है आप आर कोड के बजाय PDI कोड लिखा है? डेटा फ्रेम में डेटा प्रकारों पर ध्यान दें, उदाहरण के लिए, कारक बनाम चरित्र। खराब लिखित और कुशल आर कोड के बीच 100x गति-अप प्राप्त करना असामान्य नहीं है, जबकि समानांतर मूल्यांकन कोर की संख्या के लिए सबसे आनुपातिक है।

+0

धन्यवाद, मैं इसे आज़माउंगा। हा, मैंने वास्तव में आर कोड को शुरुआत में लिखा था और फिर इसे पीडीआई में भेज दिया था (मैं पीडीआई से आर के साथ अधिक अनुभवी हूं)। – argoneus

+0

मैंने आपके द्वारा पोस्ट किए गए 'स्प्लिट()' कोड को चलाया और लगभग एक घंटे तक इंतजार किया, लेकिन यह कभी पूरा नहीं हुआ। – argoneus

+0

विभाजन के चारों ओर जोड़े गए कुछ अतिरिक्त सुझाव, जो कि दूसरे या उससे कम के आदेश पर लेना चाहिए। हो सकता है कि कारक भी func धीमा होने के कारण भी हो? –

2

स्प्लिट (एक्स, च) धीमी गति से, अगर एक्स एक कारक है और एफ विभिन्न तत्वों का एक बहुत

तो होता है इस कोड को तेज करता है, तो:

system.time(split(seq_len(1300000), sample(250000, 1300000, TRUE))) 

लेकिन, यह बहुत धीमी है:

system.time(split(factor(seq_len(1300000)), sample(250000, 1300000, TRUE))) 

और यह फिर से तेज है, क्योंकि वहाँ केवल 25 समूहों

system.time(split(factor(seq_len(1300000)), sample(25, 1300000, TRUE))) 
हैं
संबंधित मुद्दे