23

How can I reset the time part of a pandas timestamp?

I want to reset time part in value of pandas.Timestamp.
I guess I can do it using the following procedure.

  • step 1) Timestamp to datetime type
  • step 2) datetime to seconds
  • step 3) truncate time part in seconds
  • step 4) bring back seconds to Timestamp

Even if my guess is correct, it takes too long to do. Is there a straightforward way to achieve this goal?

In [371]: ts = pd.Timestamp('2014/11/12 13:35')

In [372]: ts

Out[372]: Timestamp('2014-11-12 13:35:00')

In [373]: ts.hour = 0 # <-- this is what I am trying to do.

twasbrillig
  • 17,084
  • 9
  • 43
  • 67
Hill
  • 3,391
  • 3
  • 24
  • 28
  • If you are dealing with a ``DatetimeIndex``, you can use the `normalize` method. This is however not availabe on the individual Timestamp (a workaround is: `pd.DatetimeIndex([ts]).normalize()[0]`) – joris Nov 12 '14 at 09:40
  • Do you want to reset the 'whole' time part (only keep date), or do you only want to reset the hours? – joris Nov 12 '14 at 09:52

6 Answers6

43

I think you are looking for the replace method (see docs):

In [18]: ts
Out[18]: Timestamp('2014-11-12 13:35:00')

In [19]: ts.replace(hour=0)
Out[19]: Timestamp('2014-11-12 00:35:00')

This is a method inherited from datetime.datetime

If you want to reset the full time part, you specify all parts in replace:

In [20]: ts.replace(hour=0, minute=0, second=0)
Out[20]: Timestamp('2014-11-12 00:00:00')

There is also a DatetimeIndex.normalize method, but this isn't available on the individual Timestamps (I opened an issue for that: https://github.com/pydata/pandas/issues/8794):

In [21]: pd.DatetimeIndex([ts]).normalize()[0]
Out[21]: Timestamp('2014-11-12 00:00:00')
joris
  • 133,120
  • 36
  • 247
  • 202
  • The most valuable thing here, pandas timestamp is inherited from datetime!!! If I had known that, I wouldn't have been so scared. :) Thank you! – KateYoak Aug 30 '20 at 00:23
  • The replace method does not seem to work on a column, does it? `AttributeError: 'DatetimeProperties' object has no attribute 'replace'` – Dr_Zaszuś Jun 15 '21 at 12:44
  • 1
    Indeed, that is not available on a column/index. In that case you will need to use something like `df["col"].apply(lambda ts: ts.replace(..))` if you want to use `replace` (but note that the `normalize` is available on a column). – joris Jun 23 '21 at 05:41
2

Note that the replace method does not change the Timestamp, so if you want to keep the modified Timestamp you have to assign:

In [2]: ts = pd.Timestamp('2014/11/12 13:35')
In [3]: ts.replace(hour=0)
Out[3]: Timestamp('2014-11-12 00:35:00')
In [4]: ts
Out[4]: Timestamp('2014-11-12 13:35:00')

Note: ts is not modified in the code above.

In [5]: ts = ts.replace(hour=0)
In [6]: ts
Out[6]: Timestamp('2014-11-12 00:35:00')
Nadav Aharoni
  • 141
  • 1
  • 5
1

Instead of using datetime.datetime, use datetime.date and it will automatically truncate the hour/minute/second for you.

See https://docs.python.org/library/datetime.html#date-objects

twasbrillig
  • 17,084
  • 9
  • 43
  • 67
0
pd.Timestamp('2014-11-12 13:35') - pd.offsets.Micro(0, normalize=True) == Timestamp('2014-11-12 00:00:00')
Andy Jones
  • 4,723
  • 2
  • 19
  • 24
0

I recommend using:

pd.Timestamp('2014-11-12 13:35')-pd.Timedelta(f"{pd.Timestamp('2014-11-12 13:35').hour} hours")
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
0

There is also Timestamp.floor:

>>> ts = pd.Timestamp('2014/11/12 13:35')
>>> ts.floor('D')
Timestamp('2014-11-12 00:00:00')
>>> ts.round('D')
Timestamp('2014-11-13 00:00:00')

But, on my machine, Timestamp.normalize is almost 30 times faster than floor, and Timestamp.replace is even faster than normalize:

>>> %timeit ts.replace(hour=0, minute=0, second=0)
1.23 µs ± 17.2 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
>>> %timeit ts.normalize()
2.18 µs ± 137 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
>>> %timeit ts.floor('D')
62.7 µs ± 631 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
AXO
  • 8,198
  • 6
  • 62
  • 63