दिलचस्प पोस्ट
कैसे सी कार्यक्रम में तारीख और समय मूल्य प्राप्त करने के लिए क्या कारक PHP यूनिकोड-असंगत बनाते हैं? टूलबार को पारदर्शी बनाने के लिए कैसे? 'COLLATE SQL_Latin1_General_CP1_CI_AS' क्या करता है? क्या आपको जीसीडी में एक ब्लॉक के भीतर एक एनएसएएसयूटीओरियस पोल बनाने की आवश्यकता है? यूनिक्स कमांड का उपयोग करके जावा में मेरे मैक के सीरियल नंबर को प्रिंट करना ObservableCollection AddRange विधि का समर्थन नहीं करता है, इसलिए मुझे प्रत्येक आइटम के लिए अधिसूचित किया गया, इसके अलावा INotifyCollectionChanging के बारे में क्या? iPhone UIView एनिमेशन सर्वश्रेष्ठ अभ्यास Windows बैच फ़ाइल में आप कैसे लूप करते हैं? Q_OBJECT 'vtable के लिए अपरिभाषित संदर्भ' फेंकने एडीबी डिवाइस नाम से एंड्रॉइड एवीडी नाम कैसे प्राप्त करें क्या मैं खूबसूरत सूप के साथ स्क्रिप्ट टैग निकाल सकता हूं? यूआईपीकर देखें और एक बटन में कार्य पत्र – कैसे? PHP: स्प्लिट स्ट्रिंग पायथन में इंडेक्स का उपयोग करके पीछे की ओर लूप?

आर में मर्ज करने / डेटा में शामिल होने का सबसे तेज़ तरीका क्या है?

उदाहरण के लिए (यकीन नहीं है कि सबसे प्रतिनिधि का उदाहरण हालांकि):

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

यह मेरे पास इतनी दूर है:

 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 

वेब के समाधान से एकत्रित समाधान "आर में मर्ज करने / डेटा में शामिल होने का सबसे तेज़ तरीका क्या है?"

मैच का दृष्टिकोण तब काम करता है जब पहली बार में प्रत्येक कुंजी मान के लिए दूसरे डेटा फ्रेम में एक अनन्य कुंजी होती है। अगर दूसरी डेटा फ्रेम में डुप्लिकेट हैं तो मैच और मर्ज दृष्टिकोण समान नहीं हैं। मैच निश्चित रूप से तेजी से होता है, क्योंकि यह उतना ज्यादा नहीं कर रहा है। विशेष रूप से यह डुप्लिकेट कुंजियों के लिए कभी भी नहीं लग रहा है। (कोड के बाद जारी)

 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) bac 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] abce Levels: abcde > DF1 abc 1 1 1 a 2 1 2 b 3 2 3 c 4 2 4 e 

प्रश्न में पोस्ट किए गए sqldf कोड में, ऐसा प्रतीत हो सकता है कि अनुक्रमित दो तालिकाओं पर उपयोग किए गए थे, लेकिन वास्तव में, उन तालिकाओं पर रखा गया है, जो उस वर्ग के चयन से पहले ओवरराइट किए गए थे जो कभी भी चलाते हैं और वह, कुछ अंश में, क्यों खाते हैं इसकी इतनी धीमी गति से Sqldf का विचार यह है कि आपके आर सत्र में डेटा फ्रेम डेटा बेस का गठन होता है, स्क्लाईट में टेबल नहीं। इस प्रकार हर बार कोड एक अयोग्य तालिका नाम को संदर्भित करता है जो इसे आपके आर वर्कस्पेस में दिखता है – नहीं sqlite के मुख्य डेटाबेस में। इस प्रकार दिखाया गया है कि चयन बयान, कार्यक्षेत्र से एस 1 और डी 2 को स्केलइट के मुख्य डाटाबेस में जोड़ता है, जो अनुक्रमित के साथ वहां थे। परिणामस्वरूप यह कोई इंडेक्स नहीं होने के साथ जुड़ता है। यदि आप डी 1 और डी 2 के संस्करणों का उपयोग करना चाहते हैं जो कि एसक्यूएलईटी के मुख्य डाटाबेस में थे तो आपको उन्हें मुख्य डी 1 और मुख्य डी 2 के रूप में संदर्भित करना होगा और डी 1 और डी 2 के रूप में नहीं। इसके अलावा, यदि आप इसे जितना तेज़ हो सके चलाने का प्रयास कर रहे हैं, तो ध्यान दें कि एक साधारण जोड़ दोनों सारणियों पर अनुक्रमणिका का उपयोग नहीं कर सकता है ताकि आप एक अनुक्रमित बनाने के समय को बचा सकें। नीचे दिए गए कोड में हम इन बिंदुओं को स्पष्ट करते हैं।

यह ध्यान देने योग्य है कि सटीक कम्प्यूटेशन एक बड़ा अंतर कर सकता है जिस पर सबसे तेज़ पैकेज है उदाहरण के लिए, हम एक मर्ज और कुल मिलाकर करते हैं। हम देखते हैं कि परिणाम लगभग दो के लिए उलट हो गए हैं। सबसे तेज़ी से सबसे धीमी गति से पहले उदाहरण में हम प्राप्त करते हैं: डेटाटाहेबल, प्लायर, मर्ज और एसकेएलडीएफ, जबकि दूसरे उदाहरण में sqldf, कुल, डेटा योग्य और प्लाईर – लगभग एक के पीछे लगभग एक है। पहले उदाहरण में sqldf में डेटा की तुलना में धीमी गति से 3x धीमी है और दूसरे में इसकी 200x तेज गति से और डेटा की तुलना में 100 गुना तेज है। नीचे हम इनपुट कोड, मर्ज के लिए आउटपुट समय और कुल मिलाकर आउटपुट समय दिखाते हैं। यह भी उल्लेखनीय है कि एसक्यूएलडी एक डाटाबेस पर आधारित है और इसलिए आर से अधिक ऑब्जेक्ट्स को संभाल सकता है (यदि आप एसडीएलडीएफ के डीबीएन नाम का उपयोग करते हैं) जबकि अन्य तरीकों को मुख्य मेमोरी में प्रसंस्करण तक सीमित कर सकते हैं। इसके अलावा हमने sqldf को sqlite के साथ सचित्र किया है लेकिन यह H2 और PostgreSQL डाटाबेस को भी समर्थन करता है।

 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")) ) 

मर्ज गणना की तुलना करते हुए दो बेंचमार्क कॉल के आउटपुट हैं:

 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 

कुल गणना की तुलना करते हुए बेंचमार्क कॉल से आउटपुट हैं:

  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 

data.table लिए data.table के परिणामों में 132 सेकेंड की data.table वास्तव में आधारभूत कार्य, colMeans और cbind (स्मृति आवंटन और उन कार्यों का उपयोग करके प्रेरित नकल) का समय है। data.table का उपयोग करने के अच्छे और बुरे तरीके भी हैं।

 benchmark(replications = 1, order = "elapsed", aggregate = aggregate(d[c("x", "y")], d[c("g1", "g2")], mean), data.tableBad = { dt <- data.table(d, key = "g1,g2") dt[, colMeans(cbind(x, y)), by = "g1,g2"] }, data.tableGood = { dt <- data.table(d, key = "g1,g2") dt[, list(mean(x),mean(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")) ) test replications elapsed relative user.self sys.self 3 data.tableGood 1 0.15 1.000 0.16 0.00 5 sqldf 1 1.01 6.733 1.01 0.00 2 data.tableBad 1 1.63 10.867 1.61 0.01 1 aggregate 1 6.40 42.667 6.38 0.00 4 plyr 1 317.97 2119.800 265.12 51.05 packageVersion("data.table") # [1] '1.8.2' packageVersion("plyr") # [1] '1.7.1' packageVersion("sqldf") # [1] '0.4.6.4' R.version.string # R version 2.15.1 (2012-06-22) 

कृपया ध्यान दें कि मुझे अच्छी तरह से पता नहीं है, कृपया हेडली से plyr समय पर निर्भर होने से पहले जांच करें। यह भी ध्यान रखें कि data.table के लिए data.table को कनवर्ट करने के लिए और चाबी सेट करने के लिए समय शामिल है, फ़ारेनेस के लिए।


यह जवाब मूल रूप से दिसंबर 2010 में उत्तर देने के बाद अपडेट किया गया है। पिछले बेंचमार्क परिणाम नीचे हैं यह देखने के लिए कि क्या बदल गया है, इस उत्तर का संशोधन इतिहास देखें

  test replications elapsed relative user.self sys.self 4 data.tableBest 1 0.532 1.000000 0.488 0.020 7 sqldf 1 2.059 3.870301 2.041 0.008 3 data.tableBetter 1 9.580 18.007519 9.213 0.220 1 aggregate 1 14.864 27.939850 13.937 0.316 2 data.tableWorst 1 152.046 285.800752 150.173 0.556 6 plyrwithInternal 1 198.283 372.712406 189.391 7.665 5 plyr 1 225.726 424.296992 208.013 8.004 

सरल कार्य (जुड़ने के दोनों किनारों पर अद्वितीय मान) के लिए मैं match उपयोग करता हूं:

 system.time({ d <- d1 d$y2 <- d2$y2[match(d1$x,d2$x)] }) 

यह मर्ज से ज्यादा तेज है (मेरी मशीन पर 0.13 से 3.37 एस)।

मेरे समय:

  • merge : 3.32s
  • plyr : plyr
  • match : 0.12s

सोचा था कि मिश्रण में डीप्टर के साथ एक बेंचमार्क पोस्ट करने के लिए दिलचस्प होगा: (बहुत सी चीजें चल रही थीं)

  test replications elapsed relative user.self sys.self 5 dplyr 1 0.25 1.00 0.25 0.00 3 data.tableGood 1 0.28 1.12 0.27 0.00 6 sqldf 1 0.58 2.32 0.57 0.00 2 data.tableBad 1 1.10 4.40 1.09 0.01 1 aggregate 1 4.79 19.16 4.73 0.02 4 plyr 1 186.70 746.80 152.11 30.27 packageVersion("data.table") [1] '1.8.10' packageVersion("plyr") [1] '1.8' packageVersion("sqldf") [1] '0.4.7' packageVersion("dplyr") [1] '0.1.2' R.version.string [1] "R version 3.0.2 (2013-09-25)" 

अभी जोड़ा गया:

 dplyr = summarise(dt_dt, avx = mean(x), avy = mean(y)) 

और डेटा तालिका के साथ dplyr के लिए डेटा सेटअप करें:

 dt <- tbl_dt(d) dt_dt <- group_by(dt, g1, g2) 

अपडेट किया गया: मैंने डेटाटालेबल और पीलीर निकाल दिया है, लेकिन कुछ भी नहीं लेकिन आरस्टुडियो ओपन (i7, 16 जीबी रैम)।

डाटा के साथ 1.9 और डेटा फ्रेम के साथ dplyr:

  test replications elapsed relative user.self sys.self 2 data.tableGood 1 0.02 1.0 0.02 0.00 3 dplyr 1 0.04 2.0 0.04 0.00 4 sqldf 1 0.46 23.0 0.46 0.00 1 aggregate 1 6.11 305.5 6.10 0.02 

डाटा के साथ 1.9 और डेटा तालिका के साथ dplyr:

  test replications elapsed relative user.self sys.self 2 data.tableGood 1 0.02 1 0.02 0.00 3 dplyr 1 0.02 1 0.02 0.00 4 sqldf 1 0.44 22 0.43 0.02 1 aggregate 1 6.14 307 6.10 0.01 packageVersion("data.table") [1] '1.9.0' packageVersion("dplyr") [1] '0.1.2' 

यहाँ स्थिरता के लिए सभी डेटा और डेटा के साथ मूल है 1.9 और एक डेटा तालिका का उपयोग कर dplyr:

  test replications elapsed relative user.self sys.self 5 dplyr 1 0.01 1 0.02 0.00 3 data.tableGood 1 0.02 2 0.01 0.00 6 sqldf 1 0.47 47 0.46 0.00 1 aggregate 1 6.16 616 6.16 0.00 2 data.tableBad 1 15.45 1545 15.38 0.01 4 plyr 1 110.23 11023 90.46 19.52 

मुझे लगता है कि यह डेटा नए डेटा के लिए बहुत छोटा है। योग्य और dplyr 🙂

बड़ा डेटा सेट:

 N <- 1e8 g1 <- sample(1:50000, N, replace = TRUE) g2<- sample(1:50000, N, replace = TRUE) d <- data.frame(x=sample(N,N), y=rnorm(N), g1, g2) 

बेंचमार्क चलने से पहले डेटा को पकड़ने के लिए 10-13 जीबी मेम के आसपास ले लिया।

परिणाम:

  test replications elapsed relative user.self sys.self 1 dplyr 1 14.88 1 6.24 7.52 2 data.tableGood 1 28.41 1 18.55 9.4 

एक अरब की कोशिश की लेकिन राम उड़ा दिया 32 जीबी इसे कोई समस्या नहीं संभाल लेंगे।


[अरुण द्वारा संपादित करें] (डॉट कॉमकेन, क्या आप इस कोड को रन कर सकते हैं और अपने बेंचमार्किंग परिणाम पेस्ट कर सकते हैं? धन्यवाद)

 require(data.table) require(dplyr) require(rbenchmark) N <- 1e8 g1 <- sample(1:50000, N, replace = TRUE) g2 <- sample(1:50000, N, replace = TRUE) d <- data.frame(x=sample(N,N), y=rnorm(N), g1, g2) benchmark(replications = 5, order = "elapsed", data.table = { dt <- as.data.table(d) dt[, lapply(.SD, mean), by = "g1,g2"] }, dplyr_DF = d %.% group_by(g1, g2) %.% summarise(avx = mean(x), avy=mean(y)) ) 

अरुण के अनुरोध के अनुसार, आपने मुझे चलाने के लिए क्या प्रदान किया है:

  test replications elapsed relative user.self sys.self 1 data.table 5 15.35 1.00 13.77 1.57 2 dplyr_DF 5 137.84 8.98 136.31 1.44 

भ्रम के लिए क्षमा करें, देर रात मुझे मिल गया

डेटा फ़्रेम के साथ dplyr का उपयोग करना सारांश प्रक्रिया को कम प्रभावी तरीके लगता है। क्या डेटावेट और डेप्टर की सटीक कार्यक्षमता की तुलना में उनके डेटा संरचना पद्धतियों के साथ तुलना करने के लिए ये विधियां शामिल हैं? मैं लगभग अलग करना चाहूंगा कि जितना अधिक डाटा को साफ करने की आवश्यकता होगी, इससे पहले कि हम समूह से डेटा बनाते हैं या डाटा बनाते हैं। यह स्वाद का मामला हो सकता है लेकिन मुझे लगता है कि इसका सबसे महत्वपूर्ण हिस्सा डेटा कुशलतापूर्वक कैसे तैयार किया जा सकता है।

मर्ज फ़ंक्शन और इसके वैकल्पिक पैरामीटर का उपयोग करके:

इनर जॉइन: मर्ज (डीएफ 1, डीएफ 2) इन उदाहरणों के लिए काम करेगा क्योंकि आर आम तौर पर आम वैरिएबल नामों से फ्रेम में जुड़ जाता है, लेकिन आप निश्चित रूप से मर्ज (df1, df2, = "CustomerId" द्वारा निर्दिष्ट करना चाहते हैं) यह सुनिश्चित करने के लिए कि आप केवल वांछित क्षेत्रों पर मिलान किए गए थे आप by.x और by.y पैरामीटर का भी उपयोग कर सकते हैं यदि मिलान किए गए चर के विभिन्न डेटा फ़्रेम में अलग-अलग नाम हैं।

 Outer join: merge(x = df1, y = df2, by = "CustomerId", all = TRUE) Left outer: merge(x = df1, y = df2, by = "CustomerId", all.x = TRUE) Right outer: merge(x = df1, y = df2, by = "CustomerId", all.y = TRUE) Cross join: merge(x = df1, y = df2, by = NULL)