如何在Pandas DataFrame中指定dt.week使用北美周编号?
Got it, let's sort out this week numbering issue. The problem you're hitting is that Pandas' dt.week relies on the ISO 8601 standard, which has two key differences from the North American rules you need:
- ISO weeks start on Monday
- Week 1 is defined as the first week with at least 4 days in the new year
That's why your 2019-12-31 date is showing up as week 01—it falls in the ISO week that starts on 2019-12-30 (Monday) and includes the first few days of 2020, so ISO counts it as 2020 week 1. But your rule wants it to stay in 2019's week 53, with 2020-01-01 kicking off 2020's week 1.
Solution: Custom Week Calculation Matching Your Rules
Based on your example (2020-01-01 = week 1 2020, 2019-12-31 = week 53 2019), we can calculate weeks by treating January 1 as the start of week 1, with each week being 7 consecutive days (even if the first/last week is shorter than 7 days).
Here's the code to implement this:
# Extract the year and day-of-year for each date df['Year'] = df['Induction Date'].dt.year df['Day_of_Year'] = df['Induction Date'].dt.dayofyear # Calculate week number: (day_of_year + 6) // 7 is equivalent to ceiling(day_of_year / 7) df['Week'] = ((df['Day_of_Year'] + 6) // 7).astype(str).str.zfill(2)
How This Works
- For any date, we first get its position in the calendar year (day-of-year)
- Using
(day_of_year + 6) // 7gives us the week number by rounding up the division of day-of-year by 7. For example:- 2020-01-03 is day 3 of 2020 →
(3 + 6) // 7 = 1→ week 01 - 2019-12-31 is day 365 of 2019 →
(365 + 6) // 7 = 53→ week 53
- 2020-01-03 is day 3 of 2020 →
Optional: Alternative North American Week Rule
If you ever need to use the other common North American standard (weeks start on Sunday, week 1 is the first week containing January 1, even if it crosses into the previous year), you can use strftime("%U") with a small adjustment:
# %U counts weeks starting on Sunday, with days before the first Sunday as week 0 df['Week'] = df['Induction Date'].dt.strftime("%U").apply(lambda x: str(int(x) + 1).zfill(2))
Note that this would put 2019-12-31 into 2020's week 1, which doesn't match your example—so stick with the first solution for your specific needs.
内容的提问来源于stack exchange,提问作者Jonathan Lam

