Q&A library Python

How do I get the week number from a date in pandas?

Python Intermediate datetimeisocalendarweek

Short answer

Use dt.isocalendar().week for the ISO week number. Be careful at year boundaries, because early January can fall in week 52 or 53 of the previous ISO year.

The short version

Use dt.isocalendar(), which returns a frame with year, week and day columns, and take week. This gives the ISO week number, the standard definition. Watch the year boundary, because the ISO year is not always the calendar year, and pairing an ISO week with a calendar year will occasionally be wrong.

Getting the week

import pandas as pd

d = pd.Series(pd.to_datetime(["2021-01-04"]))

print(d.dt.isocalendar()["week"].tolist())   # [1]

isocalendar() returns three columns at once, so you can take the ISO year alongside the week, which matters for the boundary problem below.

The year-boundary trap

Under the ISO standard, a week belongs to the year containing most of its days. So the 1st of January can fall in week 52 or 53 of the previous ISO year, and late December can fall in week 1 of the next ISO year.

This means the following is subtly wrong:

df["label"] = df["date"].dt.year.astype(str) + "-W" + df["date"].dt.isocalendar()["week"].astype(str)

It mixes the calendar year with the ISO week, so a date in early January might be labelled 2021-W53 when it belongs to 2020-W53. Always take the year from isocalendar too.

iso = df["date"].dt.isocalendar()
df["label"] = iso["year"].astype(str) + "-W" + iso["week"].astype(str).str.zfill(2)

Now the year and week come from the same standard and always agree. The zfill(2) pads single digits so the labels sort correctly as text.

Grouping by week

To aggregate by week, the safest approach is usually to group by the week's start date rather than by a week number, because a real date sorts and plots correctly and carries no year ambiguity.

df.groupby(pd.Grouper(key="date", freq="W"))["amount"].sum()

freq="W" buckets by week ending on Sunday, and each group is labelled with a genuine date. This sidesteps the ISO year problem entirely, which is why it is often the better choice for reporting.

Choosing a week definition

ISO weeks start on Monday. Some organisations use Sunday-starting weeks, or a financial calendar with its own week structure. There is no universal answer, so establish which definition your work requires before you compute anything, because switching later means recomputing every figure.

The old accessor

Older code uses dt.week or dt.weekofyear. These were removed, so use dt.isocalendar().week instead. If you meet the old form in existing code, that is why it no longer runs.

Need this solved on your own data?

The library is free and always will be. When the problem is bigger than an answer, we take on the work.

Start a project