Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pandas date_range starting from the end date to start date

In am trying to generate a range of semi-annual dates using Python. Pandas provides a function pd.date_range to help with this however I would like my date range to start from the end date and iterate backwards.

For instance given the input:

start = datetime.datetime(2016 ,2, 8)
end = datetime.datetime(2018 , 6, 1)
pd.date_range(start, end, freq='6m')

The result is:

DatetimeIndex(['2016-02-29', '2016-08-31', '2017-02-28', '2017-08-31',
               '2018-02-28'])

How can I generate the following:

DatetimeIndex(['2016-02-08', '2016-06-01', '2016-12-01', '2017-06-01',
               '2017-12-01', '2018-06-01'])
like image 973
pyCthon Avatar asked Feb 16 '16 16:02

pyCthon


People also ask

What does PD date_range do?

You'll use pd. date_range when you need to have a clean series of dates to reindex your DataFrame. Pseudo Code: Create a range of timestamps at a specified start and end.

How do you select a range of date in python?

Using a DatetimeIndex: If you are going to do a lot of selections by date, it may be quicker to set the date column as the index first. Then you can select rows by date using df. loc[start_date:end_date] .

What is the date format in pandas?

By default pandas datetime format is YYYY-MM-DD ( %Y-%m-%d ). In this article, I will explain how to convert this datetime to a String format for example to MM/DD/YYYY ( %m/%d/%Y ) and to any other string date pattern.


2 Answers

With the updated output (from the edit you made) you can do something like the following:

from pandas.tseries.offsets import DateOffset

end = datetime.datetime(2018 , 6, 1)
start = datetime.datetime(2016 ,2, 8)
#Get the range of months to cover
months = (end.year - start.year)*12 + end.month - start.month
#The frequency of periods
period = 6 # in months

pd.DatetimeIndex([end - DateOffset(months=e) for e in range(0, months, period)][::-1]).insert(0, start)

This is a fairly concise solution, though I didn't compare runtimes so I'm not sure how fast it is.

Basically this is just creating the dates you need as a list, and then converting it to a datetime index.

like image 103
johnchase Avatar answered Oct 02 '22 12:10

johnchase


This can be done without pandas and using datutil instead. However it is more involved than it perhaps should:

from datetime import date
import math
from dateutil.relativedelta import relativedelta

#set up key dates
start = date(2016 ,2, 8)
end = date(2018 , 6, 1)

#calculate date range and number of 6 month periods
daterange = end-start
periods = daterange.days *2//365

#calculate next date in sequence and check for year roll-over
next_date = date(start.year,math.ceil(start.month/6)*6,1)
if next_date < start: next_date = date(next_date.year+1,next_date.month,1)

#add the first two values to a list
arr = [start.isoformat(),next_date.isoformat()]

#calculate all subsequent dates using 'relativedelta'
for i in range(periods):
    next_date = next_date+ relativedelta(months=+6)
    arr.append(next_date.isoformat())


#display results
print(arr)
like image 34
Colin Dickie Avatar answered Oct 02 '22 11:10

Colin Dickie