Chris
Chris

Reputation: 515

Python get previous day of week (Thursday in my example) from pandas date column

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

Answers (2)

Dev Khadka
Dev Khadka

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

jezrael
jezrael

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

Related Questions