2015-06-28 4 views
18

मेरे पास एक डेटा फ्रेम में एक टाइमस्टैम्प है जिसे मैं दूसरे डेटाफ्रेम से डेटा निकालने के उद्देश्य से दूसरे डेटाफ्रेम में निकटतम टाइमस्टैंप से मिलान करने का प्रयास कर रहा हूं। मेरे दृष्टिकोण की एक सामान्य उदाहरण के लिए नीचे देखें:किसी अन्य डेटासेट में निकटतम समय पर टाइमस्टैम्प डेटा मिलान करना। उचित वेक्टरकृत? तेज़ तरीका?

library(lubridate) 

data <- data.frame(datetime=ymd_hms(c('2015-04-01 12:23:00 UTC', '2015-04-01 13:49:00 UTC', '2015-04-01 14:06:00 UTC' ,'2015-04-01 14:49:00 UTC')), 
        value=c(1,2,3,4)) 
reference <- data.frame(datetime=ymd_hms(c('2015-04-01 12:00:00 UTC', '2015-04-01 13:00:00 UTC', '2015-04-01 14:00:00 UTC' ,'2015-04-01 15:00:00 UTC', '2015-04-01 16:00:00 UTC')), 
         refvalue=c(5,6,7,8,9)) 

data$refvalue <- apply(data, 1, function (x){ 
    differences <- abs(as.numeric(difftime(ymd_hms(x['datetime']), reference$datetime))) 
    mindiff <- min(differences) 
    return(reference$refvalue[differences == mindiff]) 
}) 

data 
#    datetime value refvalue 
# 1 2015-04-01 12:23:00  1  5 
# 2 2015-04-01 13:49:00  2  7 
# 3 2015-04-01 14:06:00  3  7 
# 4 2015-04-01 14:49:00  4  8 

यह ठीक काम करता है, को छोड़कर यह बहुत धीमी है, क्योंकि संदर्भ dataframe मेरी वास्तविक दुनिया आवेदन में काफी बड़ी है। क्या यह कोड सही ढंग से वेक्टरकृत है? क्या इस ऑपरेशन को करने का एक तेज, अधिक सुरुचिपूर्ण तरीका है?

+0

पायथन में यह बिल्कुल सही है कि कार्य numpy.searchsorted के लिए है। मैंने एक आर समकक्ष की तलाश की लेकिन अब तक कोई नहीं मिल सकता .. – cxrodgers

+0

@cxrodgers: इस कार्य के लिए इस कार्य के अनुप्रयोग को देखना दिलचस्प होगा। टीआईएस दस्तावेज को देखने के बाद, मैं अपने सिर को खरोंच कर रहा हूं कि यह कैसे करेगा। क्या आपको एक ऐसा काम करने वाला उदाहरण मिल सकता है? –

+0

@ बॉन्डडडस्ट यहां बीआई रिको द्वारा प्रदान किए गए उत्तर को देखें: http://stackoverflow.com/questions/8914491/finding-the-nearest-value-and-return-the-index-of-array-in-python – cxrodgers

उत्तर

15

मैंने सोचा कि अगर यह गति के लिए एक data.table समाधान से मेल करने में सक्षम होगा का उपयोग कर शामिल हो सकते हैं, लेकिन यह एक आधार-आर vectorized समाधान है जो अपने apply संस्करण को बेहतर प्रदर्शन करना चाहिए। और चूंकि यह वास्तव में कभी दूरी की गणना नहीं करता है, यह वास्तव में डेटा.table-निकटतम दृष्टिकोण से तेज़ हो सकता है। यह अंतराल के मध्य बिंदुओं की लंबाई को सबसे कम संभव मूल्य या अंतराल के प्रारंभिक बिंदु को "मध्य-ब्रेक" का सेट बनाने के लिए जोड़ता है और फिर समय को संसाधित करने के लिए findInterval फ़ंक्शन का उपयोग करता है। यह reference डेटासेट की पंक्तियों में एक उपयुक्त अनुक्रमणिका बनाता है और "refvalue" को data -object पर "स्थानांतरित" किया जा सकता है।

data$reefvalue <- reference$refvalue[ 
         findInterval(data$datetime, 
            c(-Inf, head(reference$datetime,-1))+ 
            c(0, diff(as.numeric(reference$datetime))/2)) ] 
# values are [1] 5 7 7 8 
+0

धन्यवाद एक गुच्छा। यह अच्छी तरह से काम करता है। – user278411

15

आप data.table रों रोलिंग की कोशिश "निकटतम" विकल्प

library(data.table) # v1.9.6+ 
setDT(reference)[data, refvalue, roll = "nearest", on = "datetime"] 
# [1] 5 7 7 8 
+1

एक में लाइन (इंडेक्स प्राप्त किए बिना): 'setDT (डेटा) [, refvalue: = setkey (setDT (संदर्भ), डेटाटाइम) [डेटा, refvalue, रोल = "निकटतम"]]' - यह नो के साथ जुड़ने पर बहुत अच्छा हो जाएगा चाबियाँ लागू की गई हैं। – Arun

+0

@ अरुण धन्यवाद, फिर भी दो कदम मेरे लिए अधिक पठनीय दिखते हैं हालांकि ... –

+0

निश्चित रूप से। मैं सहमत हूँ। – Arun

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