user7038639
user7038639

Reputation: 89

Problems with adding +1 (period) and -1 day with dateutil's relativedelta

I'm getting a class typeerror using dateutil's relative delta. My code is here:

#import packages
import numpy as np
import pandas as pd
import datetime as dt
from dateutil.relativedelta import relativedelta
from pandas import DataFrame
from pandas import Series

#timing
pers = 12
monthpp = 1
month_per = int(pers/monthpp)

sdate = dt.date(2016,1,1)
ops = dt.date(2016,3,15)

bop1 = sdate
eop1 = bop1 + relativedelta(months =+ 1, days =- 1)
edate = sdate + relativedelta(months =+ month_per)

rng_bop = pd.date_range(bop1, freq = 'MS', periods = pers)
rng_eop = pd.date_range(eop1, freq = 'M', periods = pers)

ops_line = ops >= rng_bop and ops <= rng_eop

#outputs
print(sdate)
print(edate)
print(rng_bop)
print(rng_eop)

If someone has a better alternative to my method, I'd be open to it - I'm trying to translate excel stuff into python and might not be doing it super effectively.

My end goal for this part is to be able to adjust the period by months, quarters or semi-annual or years, but I'd be happy with just months for now. The EOP line should be the (BOP + Period - 1 day).

I also don't think that my ops_line definition will work - I'm trying to create a boolean array from the logical operators. Any points?

Upvotes: 0

Views: 2399

Answers (3)

Joel Cross
Joel Cross

Reputation: 1450

I have a similar problem with pandas date range. I tried using DateOffset with no success, then I discovered this:

Adding and subtracting integers from periods shifts the period by its own frequency. Arithmetic is not allowed between Period with different freq (span).

It turns out the answer is actually really simple! Assuming your Period and PeriodRange objects have freq == "M" you can add to them by adding regular numbers:

>>> period
Period('2020-01', 'M')
>>> period + 1
Period('2020-02', 'M')
>>> period_range
PeriodIndex(['2020-01', '2020-02', '2020-03', '2020-04', '2020-05', '2020-06',
             '2020-07', '2020-08', '2020-09', '2020-10', '2020-11', '2020-12'],
            dtype='period[M]', freq='M')

>>> period_range + 1
PeriodIndex(['2020-02', '2020-03', '2020-04', '2020-05', '2020-06', '2020-07',
             '2020-08', '2020-09', '2020-10', '2020-11', '2020-12', '2021-01'],
            dtype='period[M]', freq='M')

I know this question is quite old now, but hopefully my answer is helpful to somebody!

Upvotes: 0

SiHa
SiHa

Reputation: 8411

As Leo Wahyd mentions =+ / =- is invalid syntax in most languages.

Reading the documentation:

years, months, weeks, days, hours, minutes, seconds, microseconds:
Relative information, may be negative (argument is plural); adding or subtracting a relativedelta with relative information performs the corresponding aritmetic operation on the original datetime value with the information in the relativedelta.

I think, actually, it it should be:

eop1 = bop1 + relativedelta(months = 1, days = -1)
edate = sdate + relativedelta(months = month_per)

Upvotes: 0

Leo wahyd
Leo wahyd

Reputation: 207

it should be months += 1, days-= 1 notmonths =+ 1, days =- 1 as the latter one assigns months and days to 1, and -1 respectively

Upvotes: 1

Related Questions