Reputation: 515
I have a pandas date column and I want to return the date for the previous Thursday (could be any day of week). I use pd.offsets.Week but I do not get the expected result when the year changes and the Week starts over. Here is my dataframe as 'd':
raw date Thursday week_start
0 2019-01-03 2018-12-27 2018-12-27
1 2019-01-03 2018-12-27 2018-12-27
2 2019-01-03 2018-12-27 2018-12-27
3 2019-01-02 2018-12-27 2018-12-27
4 2019-01-02 2018-12-27 2018-12-27
5 2019-01-02 2018-12-27 2018-12-27
6 2019-01-03 2019-01-03 2018-12-27
7 2019-01-03 2019-01-03 2018-12-27
8 2019-01-03 2019-01-03 2018-12-27
9 2019-01-03 2019-01-03 2018-12-27
10 2019-01-02 2018-12-27 2018-12-27
11 2019-01-02 2018-12-27 2018-12-27
12 2019-01-02 2018-12-27 2018-12-27
d['week_start'] = d['raw date'] - pd.offsets.Week(weekday=3)
I expected where d['week_start'] = 1/3/2019 to return 1/3/2019, not 12/27/2018. I suspect it is because the Week at 1/3/2019 is 0 so it returns the Thursday of that week. How can I get the previous Thursday's date regardless of a change in the year?
Upvotes: 1
Views: 499
Reputation: 5451
this can be done using pd.TimeDeltaIndex.
df["date"].dt.dayofweek-3+7) will give days before Thursday of next week
df["date"].dt.dayofweek-3+7)%7 will give days after last Thursday
date_range = pd.date_range('2019-9-20', periods=20)
df = pd.DataFrame({'date': date_range})
df["week_start"] = df["date"] - pd.TimedeltaIndex((df["date"].dt.dayofweek-3+7)%7, "D")
df
Result
date date dayofweek week_start week_start dayofweek
0 2019-09-20 4 2019-09-19 3
1 2019-09-21 5 2019-09-19 3
2 2019-09-22 6 2019-09-19 3
3 2019-09-23 0 2019-09-19 3
4 2019-09-24 1 2019-09-19 3
5 2019-09-25 2 2019-09-19 3
6 2019-09-26 3 2019-09-26 3
7 2019-09-27 4 2019-09-26 3
8 2019-09-28 5 2019-09-26 3
9 2019-09-29 6 2019-09-26 3
10 2019-09-30 0 2019-09-26 3
11 2019-10-01 1 2019-09-26 3
12 2019-10-02 2 2019-09-26 3
13 2019-10-03 3 2019-10-03 3
14 2019-10-04 4 2019-10-03 3
15 2019-10-05 5 2019-10-03 3
16 2019-10-06 6 2019-10-03 3
17 2019-10-07 0 2019-10-03 3
18 2019-10-08 1 2019-10-03 3
19 2019-10-09 2 2019-10-03 3
Upvotes: 0
Reputation: 862511
You can use Series.where
with Series.dt.weekday
for change only not Thursday
values:
rng = pd.date_range('2019-01-03', periods=20)
d = pd.DataFrame({'raw date': rng})
mask = d['raw date'].dt.weekday == 3
d['week_start'] = d['raw date'].where(mask, d['raw date'] - pd.offsets.Week(weekday=3))
print(d)
raw date week_start
0 2019-01-03 2019-01-03
1 2019-01-04 2019-01-03
2 2019-01-05 2019-01-03
3 2019-01-06 2019-01-03
4 2019-01-07 2019-01-03
5 2019-01-08 2019-01-03
6 2019-01-09 2019-01-03
7 2019-01-10 2019-01-10
8 2019-01-11 2019-01-10
9 2019-01-12 2019-01-10
10 2019-01-13 2019-01-10
11 2019-01-14 2019-01-10
12 2019-01-15 2019-01-10
13 2019-01-16 2019-01-10
14 2019-01-17 2019-01-17
15 2019-01-18 2019-01-17
16 2019-01-19 2019-01-17
17 2019-01-20 2019-01-17
18 2019-01-21 2019-01-17
19 2019-01-22 2019-01-17
Upvotes: 1