Home > Mobile >  How to identify if two isocalendar tuples are consecutive in Python
How to identify if two isocalendar tuples are consecutive in Python

Time:02-18

I am looking for a way to determine if two isocalendar tuples are consecutive using Python.

The tuples are obtained by using the datetime.isocalendar() as below:

datelist = pd.date_range(datetime.strptime("29-Dec-2022", "%d-%b-%Y").date(), periods=11).tolist()
for i in range (len ( datelist)):
    datelist [i] =datelist [i].isocalendar() 

datelist
 (2022, 52, 5),
 (2022, 52, 6),
 (2022, 52, 7),
 (2023, 1, 1),
 (2023, 1, 2),
 (2023, 1, 3),
 (2023, 1, 4),
 (2023, 1, 5),
 (2023, 1, 6),
 (2023, 1, 7)]

I am looking for a way to check that (2023,1,1) is the isoweek that follows (2023,52,7) and so on.

I tried two approaches that did not work.

The first is extracting the week number from the tuple and checking if it's consecutive by using the integer. This logic works in most week but not when there is a change of year, as in the example above.

The second approach I tried is using logical operators on the isocalendar tuple itself, such as:

 (2022, 52, 7)   relativedelta(weeks=1)

However, this produces errors.

Can you recommend a Pythonic way to achieve this on a Pandas DataFrame?

My final objective after establishing if two tuples represent consecutive isoweek is to use Groupby to group dates only in consecutive weeks.

Many thanks in advance to the community for the help.

CodePudding user response:

The pandas version:

df = pd.DataFrame({'isocal': datelist})

df['check'] = df['isocal'].apply(lambda x: datetime.fromisocalendar(*x)) \
                          .diff().eq(pd.Timedelta(days=1))

Output:

>>> df
           isocal  check
0   (2022, 52, 4)  False
1   (2022, 52, 5)   True
2   (2022, 52, 6)   True
3   (2022, 52, 7)   True
4    (2023, 1, 1)   True
5    (2023, 1, 2)   True
6    (2023, 1, 3)   True
7    (2023, 1, 4)   True
8    (2023, 1, 5)   True
9    (2023, 1, 6)   True
10   (2023, 1, 7)   True

CodePudding user response:

Convert the ISO calendar to date then use relativedelta to check if the current date following the previous date:

from datetime import date

dt = [date.fromisocalendar(*x) for x in datelist]

out = ['N/A']   [curr   relativedelta(days=-1) == prev
                    for curr, prev in zip(dt[1:], dt)]

Output:

>>> out
['N/A', True, True, True, True, True, True, True, True, True, True]

CodePudding user response:

As I understand, the core of the problem is to check whether one isocalendar date is in the week after another isocalendar date, not day as as other answers here indicate.

As you have described yourself, it is not possible to make any date calculations on your isocalendar dates. This is because they are simply named tuples see docs here. You can however convert them into a datetime object, do the arithmetic (add one week), and then convert them back and see if they are the same week:

def is_consecutive(curr, consecutive_candidate):
    curr_dt = date.fromisocalendar(*curr)
    consec_dt = date.fromisocalendar(*consecutive_candidate)
    return datetime.isocalendar(curr_dt   timedelta(weeks=1)).week
    == datetime.isocalendar(consec_dt).week

Now use this function directly on your datelist list, e.g.:

is_consecutive(datelist[3], datelist[4])
# True

is_consecutive(datelist[4], datelist[5])
# False

The first one is True since 1.jan 2023 (dt[3]) is Sunday of the last week of 2022 (according to ISO week date) and 2.jan (dt[4]) is Monday of the first week of 2023

  • Related