2015-04-18 10 views
9

मैं एक API जहां मैं अपने अनुरोध, पूर्व के लिए तिथि सीमा प्रदान करने की आवश्यकता के माध्यम से कुछ डेटा तक पहुँचने कर रहा हूँ। प्रारंभ = '20100101', अंत = '20150415'। मैंने सोचा कि मैं तारीख सीमा को गैर-ओवरलैपिंग अंतराल में तोड़कर और प्रत्येक अंतराल पर मल्टीप्रोसेसिंग का उपयोग करके इसे तेज कर दूंगा।एक तिथि सीमा कैसे हम इसे तोड़ सकते हैं अप एन सन्निहित उप अंतराल में देखते हुए?

मेरे समस्या यह है कि मैं कैसे तिथि सीमा को तोड़ने रहा है नहीं लगातार मुझे उम्मीद परिणाम दे रही है। यहाँ मैं क्या किया है है:

from datetime import date 

begin = '20100101' 
end = '201' 

मान लीजिए हम तिमाहियों में इस को तोड़ने के लिए चाहता था।

def get_yyyy_mm_dd(yyyymmdd): 
    # given string 'yyyymmdd' return (yyyy, mm, dd) 
    year = yyyymmdd[0:4] 
    month = yyyymmdd[4:6] 
    day = yyyymmdd[6:] 
    return int(year), int(month), int(day) 

y1, m1, d1 = get_yyyy_mm_dd(begin) 
d1 = date(y1, m1, d1) 
y2, m2, d2 = get_yyyy_mm_dd(end) 
d2 = date(y2, m2, d2) 

फिर उप अंतराल में इस सीमा को विभाजित:: सबसे पहले मैं तारीखों में स्ट्रिंग को बदलने

def remove_tack(dates_list): 
    # given a list of dates in form YYYY-MM-DD return a list of strings in form 'YYYYMMDD' 
    tackless = [] 
    for d in dates_list: 
     s = str(d) 
     tackless.append(s[0:4]+s[5:7]+s[8:]) 
    return tackless 

def divide_date(date1, date2, intervals): 
    dates = [date1] 
    for i in range(0, intervals): 
     dates.append(dates[i] + (date2 - date1)/intervals) 
    return remove_tack(dates) 

शुरू करते हैं और हम ऊपर से अंत का प्रयोग मिलता है:

listdates = divide_date(d1, d2, 4) 
print listdates # ['20100101', '20100402', '20100702', '20101001', '201'] looks correct 

लेकिन अगर बजाय मैं तिथियों का उपयोग करता हूं:

begin = '20150101' 
end = '20150228' 

...

listdates = divide_date(d1, d2, 4) 
print listdates # ['20150101', '20150115', '20150129', '20150212', '20150226'] 

मुझे फरवरी के अंत में दो दिन याद आ रही है। मुझे अपने आवेदन के लिए समय या समय क्षेत्र की आवश्यकता नहीं है और मुझे दूसरी लाइब्रेरी इंस्टॉल करने में कोई फर्क नहीं पड़ता।

उत्तर

12

मैं वास्तव में एक अलग दृष्टिकोण का पालन करें और timedelta और तारीख के अलावा पर भरोसा करते हैं गैर-अतिव्यापी पर्वतमाला

कार्यान्वयन

def date_range(start, end, intv): 
    from datetime import datetime 
    start = datetime.strptime(start,"%Y%m%d") 
    end = datetime.strptime(end,"%Y%m%d") 
    diff = (end - start)/intv 
    for i in range(intv): 
     yield (start + diff * i).strftime("%Y%m%d") 
    yield end.strftime("%Y%m%d") 

निष्पादन निर्धारित करने के लिए होगा

>>> begin = '20150101' 
>>> end = '20150228' 
>>> list(date_range(begin, end, 4)) 
['20150101', '20150115', '20150130', '20150213', '20150228'] 
+0

वर्क्स महान! संक्षिप्त और मेरे सभी मध्यवर्ती कार्यों के बिना। धन्यवाद! – Scott

+1

बस कुछ ऐसा देखा जो शायद आप संपादित करना चाहें।आपके उत्तर में: उपज (डी 1 + diff * i) .strftime ("% Y% m% d"), डी 1 एक वैश्विक है और मेरे कोड के साथ काम करता है, लेकिन सामान्य डी 1 में शुरू होना चाहिए। – Scott

+0

@ स्कॉट: धन्यवाद। मेरा मूल कोड डी 1, डी 2 वैरिएबल के साथ था, लेकिन बाद में इसे इस पोस्ट में सार्थक कुछ चीज़ों में बदल दिया, लेकिन प्रतीत होता है कि संपादन में कुछ याद आया। – Abhijit

1

सका आप इसके बजाय datetime.date ऑब्जेक्ट्स का उपयोग करते हैं?

यदि आप कार्य करें:

import datetime 
begin = datetime.date(2001, 1, 1) 
end = datetime.date(2010, 12, 31) 

intervals = 4 

date_list = [] 

delta = (end - begin)/4 
for i in range(1, intervals + 1): 
    date_list.append((begin+i*delta).strftime('%Y%m%d')) 

और date_list प्रत्येक inteval के लिए अंतिम तिथि आ होनी चाहिए।

2

आप datetime के लिए तारीख बदलना चाहिए

from datetime import date, datetime, timedelta 

begin = '20150101' 
end = '20150228' 

def get_yyyy_mm_dd(yyyymmdd): 
    # given string 'yyyymmdd' return (yyyy, mm, dd) 
    year = yyyymmdd[0:4] 
    month = yyyymmdd[4:6] 
    day = yyyymmdd[6:] 
    return int(year), int(month), int(day) 

y1, m1, d1 = get_yyyy_mm_dd(begin) 
d1 = datetime(y1, m1, d1) 
y2, m2, d2 = get_yyyy_mm_dd(end) 
d2 = datetime(y2, m2, d2) 

def remove_tack(dates_list): 
    # given a list of dates in form YYYY-MM-DD return a list of strings in form 'YYYYMMDD' 
    tackless = [] 
    for d in dates_list: 
    s = str(d) 
    tackless.append(s[0:4]+s[5:7]+s[8:]) 
    return tackless 

def divide_date(date1, date2, intervals): 
    dates = [date1] 
    delta = (date2-date1).total_seconds()/4 
    for i in range(0, intervals): 
    dates.append(dates[i] + timedelta(0,delta)) 
    return remove_tack(dates) 

listdates = divide_date(d1, d2, 4) 
print listdates 

परिणाम:

[ '20,150,101 00:00:00', '20,150,115 00:00:00', '20,150,130 00:00: 00 ',' 20,150,213 00:00:00 ',' 20,150,228 00:00:00 ']

+0

इसे इंगित करने के लिए धन्यवाद। मैंने @ अभिजीत के जवाब को स्वीकार कर लिया क्योंकि यह मेरे कोड को थोड़ा सा साफ करता है। – Scott

+0

@ निश्चित रूप से, अभिजीत का जवाब बेहतर है, मैं भी उसके लिए वोट देता हूं;) –

1

पांडा से Datetimeindex और काल का उपयोग करना, एक साथ शब्दकोश समझ के साथ:

import pandas as pd 

begin = '20100101' 
end = '201' 

start = dt.datetime.strptime(begin, '%Y%m%d') 
finish = dt.datetime.strptime(end, '%Y%m%d') 

dates = pd.DatetimeIndex(start=start, end=finish, freq='D').tolist() 
quarters = [d.to_period('Q') for d in dates] 
df = pd.DataFrame([quarters, dates], index=['Quarter', 'Date']).T 

quarterly_dates = {str(q): [ts.strftime('%Y%m%d') 
          for ts in df[df.Quarter == q].Date.values.tolist()] 
          for q in quarters} 

>>> quarterly_dates 
{'2010Q1': ['20100101', 
    '20100102', 
    '20100103', 
    '20100104', 
    '20100105', 
... 
    '20101227', 
    '20101228', 
    '20101229', 
    '201', 
    '201']} 

>>> quarterly_dates.keys() 
['2010Q1', '2010Q2', '2010Q3', '2010Q4'] 
संबंधित मुद्दे