0

I have a numpy array which has a long list of datetimes. I was wondering is there a way to add a year to all values of the array at once without using a for loop? eg. Using some numpy or datetime module?

>>> import datetime
>>> import numpy as np

>>> dts.shape
(64580,)

>>> dts[:5]
array([datetime.date(2000, 1, 15), datetime.date(2000, 1, 15),
       datetime.date(2000, 1, 15), datetime.date(2000, 1, 15),
       datetime.date(2000, 1, 15)], dtype=object)

>>> new_dts = somemodule.somefunctionforaddingyearorsomething(dts, year=1)
>>> new_dts
array([datetime.date(2001, 1, 15), datetime.date(2001, 1, 15),
       datetime.date(2001, 1, 15), datetime.date(2001, 1, 15),
       datetime.date(2001, 1, 15)], dtype=object)

Note: Day of each date is always set to day 15 as the dates represent monthly mean data.

I have implemented it using a for loop however this can be computationally slow..

The code for that is here:

def add_year_to_Datelist(dl):

dts = dl.dates.copy()
for idx, date in enumerate(dts):
    dts[idx] = date.replace(year=date.year + 1)

dl.set_dates(dts)
return dl

Cheers

2 Answers 2

3

NumPy doesn't support "1 year" as a timedelta, since this can be 365 or 366 days. If you are willing to use Pandas, you can use pd.to_datetime with pd.DateOffset, which does support year-based offsets:

import datetime, numpy as np, pandas as pd

dts = np.array([datetime.date(2000, 1, 15), datetime.date(2000, 1, 15),
                datetime.date(2000, 1, 15), datetime.date(2000, 1, 15),
                datetime.date(2000, 1, 15)], dtype=object)

dts = (pd.to_datetime(dts) + pd.DateOffset(years=1)).values.astype('datetime64[D]')

# array(['2001-01-15', '2001-01-15', '2001-01-15', '2001-01-15',
#        '2001-01-15'], dtype='datetime64[D]')

With NumPy, you can add a fixed number of days after converting your object dtype array to np.datetime64:

dts = dts.astype(np.datetime64) + np.timedelta64(365, 'D')

# array(['2001-01-14', '2001-01-14', '2001-01-14', '2001-01-14',
#        '2001-01-14'], dtype='datetime64[D]')

Note the 1-day mismatch between the two results.

Sign up to request clarification or add additional context in comments.

2 Comments

Your pandas answer works perfectly! Although I tried the first answer and noticed that for any leap year the data will be incorrect. i.e months Jan/Feb have day value of 14 whereas the other months have day values of 15..
@MaxCollier, Yes, that's exactly the problem with using 365 days fixed. There's no native NumPy solution as far as I'm aware.
2

Making things faster while using a for loop is kind of hard. Using map however brings the calculations into C and can speed things up considerably.

Try this:

def add_year(dl, add=1):
    """Return new list with year increased by specified amount."""
    dts = list(map(lambda date: date.replace(year = date.year + add), dl.dates.copy()))
    return dts

Not sure how to get a numpy list because I haven't worked with numpy yet (I know, pathetic...) but you know so yeah :D

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.