BallpointBen
BallpointBen

Reputation: 13750

"Resample" a timestamp according to its frequency

I have a pandas Timestamp with a datetime and frequency associated. However, the datetime seems to be independent of the frequency. For instance,

>>> t = pd.Timestamp('2018-6-6', freq='W-FRI')
>>> t
Timestamp('2018-06-06 00:00:00')

June 6, 2018 is not a Friday. How can I get June 1, 2018 (the previous Friday) from this Timestamp? (If the Timestamp were June 1, 2018 then it should return June 1, 2018.) The following works but seems too verbose.

>>> friday = (pd.date_range(t + pd.Timedelta('1D'), 
                            periods=1, 
                            freq='W-FRI')
              - 1)[0]
>>> friday
Timestamp('2018-06-01 00:00:00', freq='W-FRI')

Upvotes: 2

Views: 1153

Answers (4)

BallpointBen
BallpointBen

Reputation: 13750

After some digging around, it seems that rollback is the perfect method for this. (If we'd wanted the next Friday instead of the previous Friday we could use rollforward.) There are two ways to create the offset object with a frequency of W-FRI:

# Method 1
>>> from pandas.tseries.offsets import Week
>>> w_fri = Week(weekday=4) # Mon == 0, Tue == 1, ..., Sun = 6
>>> w_fri
<Week: weekday=4>

# Method 2
>>> from pandas.tseries.frequencies import to_offset
>>> w_fri = to_offset('W-FRI')
>>> w_fri
<Week: weekday=4>

Then to do the rollback,

>>> w_fri.rollback(pd.Timestamp('2019-1-17'))  # A Thursday
Timestamp('2019-01-11 00:00:00')
>>> w_fri.rollback(pd.Timestamp('2019-1-18'))  # A Friday
Timestamp('2019-01-18 00:00:00')

More info here

Upvotes: 0

Anton vBR
Anton vBR

Reputation: 18906

OR we could use an if-statement to not move the date if it is friday (4) already. Thanks to @Ben.T we can compare it to the defined freq-weekday and thus make it a bit more generic.

import pandas as pd

t = pd.Timestamp('2018-6-7', freq='W-FRI')
friday = t if t.weekday() == t.freq.weekday else t-1

print(friday)

Returns:

2018-06-01 00:00:00

Upvotes: 2

Ben.T
Ben.T

Reputation: 29635

Another possibility is to use the methods weekday of t and the fact that the freq.weekday is accessible from t:

t - pd.Timedelta(days = (t.weekday() - t.freq.weekday)%7 )

Upvotes: 1

SciPy
SciPy

Reputation: 6090

>>> friday = [d for d in pd.date_range(end='2018-6-6', periods=7, freq='D') 
      if d.dayofweek == 4]
>>> print(friday)

[Timestamp('2018-06-01 00:00:00', freq='D')]

Upvotes: 0

Related Questions