2013-10-30 3 views
6

औसत समय की समस्या का सबसे तेज़ समाधान ढूंढने के लिए औसत समय।डेटाटाइम सूची

मुझे डेटाटाइम ऑब्जेक्ट्स की एक सूची मिली है। समय के औसत मूल्य (वर्ष, महीने, दिन को छोड़कर) खोजने की आवश्यकता है।

import datetime as dtm 
def avg_time(times): 
    avg = 0 
    for elem in times: 
     avg += elem.second + 60*elem.minute + 3600*elem.hour 
    avg /= len(times) 
    rez = str(avg/3600) + ' ' + str((avg%3600)/60) + ' ' + str(avg%60) 
    return dtm.datetime.strptime(rez, "%H %M %S") 
+1

अपने प्रश्न क्या है? क्या यह आपके उद्देश्य के लिए पर्याप्त तेज़ नहीं है? तब कितना तेज़ होना होगा? संदर्भ क्या है (यानी, एक अलग दृष्टिकोण हो सकता है जो तेज़ है और इस दिनचर्या को छोड़ देता है)? – Evert

+0

मेरा सवाल यह है कि समग्र गति में सुधार कैसे करें। जितना तेज़ हो उतना तेज़ पायथन पर हो सकता है। हो सकता है कि ऐसा करने के लिए कुछ कार्य या वैकल्पिक तरीका हो। महत्वपूर्ण नोट: मूल रूप से औसत के लिए डेटा पांडा डेटाफ्रेम कॉलम (डेटाटाइम 64 [एनएस] प्रकार) से आ रहा है – user2915556

उत्तर

4

यहाँ मैं अब तक क्या मिला है इस समस्या से संपर्क करने के लिए यहां एक बेहतर तरीका है

जीन datetimes का एक नमूना दर

In [28]: i = date_range('20130101',periods=20000000,freq='s') 

In [29]: i 
Out[29]: 
<class 'pandas.tseries.index.DatetimeIndex'> 
[2013-01-01 00:00:00, ..., 2013-08-20 11:33:19] 
Length: 20000000, Freq: S, Timezone: None 

औसत 20 मीटर बार

In [30]: %timeit pd.to_timedelta(int((i.hour*3600+i.minute*60+i.second).mean()),unit='s') 
1 loops, best of 3: 2.87 s per loop 

एक timedelta के रूप में परिणाम (ध्यान दें कि यह आवश्यकता है numpy 1.7 और to_timedelta भाग के लिए 0.13 पांडा, बहुत जल्द ही आ रहा है)

In [31]: pd.to_timedelta(int((i.hour*3600+i.minute*60+i.second).mean()),unit='s') 
Out[31]: 
0 11:59:12 
dtype: timedelta64[ns] 

सेकेंड में (यह पांडा 0.12, numpy> = 1.6) के लिए काम करेगा।

In [32]: int((i.hour*3600+i.minute*60+i.second).mean()) 
Out[32]: 43152 
+0

मुझे लगता है कि pandas.tseries.index.DatetimeIndex है। मेरा डेटा (डीएफ ['तिथि']) में pandas.core.series.Series प्रकार है। क्या आप सुझाव दे सकते हैं कि इसे कैसे परिवर्तित किया जाए? – user2915556

+0

'' इंडेक्स (your_series) '' – Jeff

+0

यह 4.78 सेकेंड बनाम अच्छा पुराना 37.7 सेकेंड 2 9 एम बेस ('% टाइमिट 'पर) के साथ काम करता है। मुझे लगता है कि यह है। धन्यवाद! – user2915556

0

आपको कम से कम एक जनरेटर अभिव्यक्ति के साथ sum() का उपयोग सेकंड की कुल संख्या बनाने के लिए होगा::

from datetime import datetime, date, time 

def avg_time(datetimes): 
    total = sum(dt.hour * 3600 + dt.minute * 60 + dt.second for dt in datetimes) 
    avg = total/len(datetimes) 
    minutes, seconds = divmod(int(avg), 60) 
    hours, minutes = divmod(minutes, 60) 
    return datetime.combine(date(1900, 1, 1), time(hours, minutes, seconds)) 

डेमो:

>>> from datetime import datetime, date, time, timedelta 
>>> def avg_time(datetimes): 
...  total = sum(dt.hour * 3600 + dt.minute * 60 + dt.second for dt in datetimes) 
...  avg = total/len(datetimes) 
...  minutes, seconds = divmod(int(avg), 60) 
...  hours, minutes = divmod(minutes, 60) 
...  return datetime.combine(date(1900, 1, 1), time(hours, minutes, seconds)) 
... 
>>> avg_time([datetime.now(), datetime.now() - timedelta(hours=12)]) 
datetime.datetime(1900, 1, 1, 7, 13) 
+0

मुझे यकीन नहीं है कि मैं बिना टाइमटाटा के साथ मिल सकता हूं। यह मेरे पांडा डेटाफ्रेम में कॉलम में से एक है, जिसे मुझे सौदा करने की आवश्यकता है। क्या आप sum() जनरेटर लूप का उपयोग करने के बारे में थोड़ा और विशिष्ट हो सकते हैं? – user2915556

+0

@ user2915556: पांडा में ऐसा करने के लिए * बेहतर * हो सकता है; मुझे पता नहीं है कि मेरे पास पांडा के साथ अनुभव नहीं है। शायद यह आपके प्रश्न में कहा जा सकता था (जिसमें आपके डेटाफ्रेम जैसा दिखता है) का विवरण शामिल है। मैंने आपके प्रश्न में 'पांडा' टैग जोड़ने की स्वतंत्रता ली है। मैंने 'timedelta' ऑब्जेक्ट्स का उपयोग करने से बचने के लिए अपना जवाब अपडेट कर दिया है। –

+0

बहुत बहुत धन्यवाद! पांडा डेटा के साथ चलते समय (avg_time (df ['date'])) यह 24.3 सेकंड (प्रारंभिक संस्करण के बनाम 24.1) में चलता है। लेकिन जब मैंने सूची में तारीखों को परिवर्तित करने की कोशिश की (डीएफ ['डेटा']। टोस्ट() जो 27.3 सेकेंड ले गया) यह 4.12 बनाम 4.26 – user2915556

0

मैं इसकी तलाश कर रहा था, लेकिन फिर मैंने इसे खोज लिया। डेटाटाइम ऑब्जेक्ट की सूची का औसत प्राप्त करने का एक बहुत ही आसान तरीका।

import datetime 
    #from datetime.datetime import timestamp,fromtimestamp,strftime ----> You can use this as well to remove unnecessary datetime.datetime prefix :) 
    def easyAverage(datetimeList): ----> Func Declaration 
     sumOfTime=sum(map(datetime.datetime.timestamp,datetimeList)) 
     ''' 
     timestamp function changes the datetime object to a unix timestamp sort of a format. 
     So I have used here a map to just change all the datetime object into a unix time stamp form , added them using sum and store them into sum variable. 
     ''' 
     length=len(datetimeList) #----> Self Explanatory 

     averageTimeInTimeStampFormat=datetime.datetime.fromtimestamp(sumOfTime/length) 
     ''' 
     fromtimestamp function returns a datetime object from a unix timestamp. 
     ''' 

     timeInHumanReadableForm=datetime.datetime.strftime(averageTimeInTimeStampFormat,"%H:%M:%S") #----> strftime to change the datetime object to string. 
     return timeInHumanReadableForm 

या आप एक साधारण लाइन में यह सब कर सकते हैं:

avgTime=datetime.datetime.strftime(datetime.datetime.fromtimestamp(sum(map(datetime.datetime.timestamp,datetimeList))/len(datetimeList)),"%H:%M:%S") 

चीयर्स,

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