30

I was trying to round off time to the nearest hour in python in a dataframe.

Suppose if a timestamp is 2017-11-18 0:16 it should come as 2017-11-18 0:00 and 2017-11-18 1:56 should round off as 2017-11-18 2:00

4
  • 1
    What did you try? Commented Feb 22, 2018 at 22:00
  • Show us some code, why are you not getting it? Commented Feb 22, 2018 at 22:02
  • Please (re-)read "How to Ask", then edit your question to include a minimal reproducible example that demonstrates what you've tried and what didn't work. Commented Feb 22, 2018 at 22:55
  • @user123, did one of the below solutions help? if so, feel free to accept one (tick on left). Commented Feb 28, 2018 at 11:34

6 Answers 6

47

I experimented a bit with jpp but ended up with a different solution as adding one hour at hour 23 crashed the thing.

from datetime import datetime, timedelta now = datetime.now() def hour_rounder(t): # Rounds to nearest hour by adding a timedelta hour if minute >= 30 return (t.replace(second=0, microsecond=0, minute=0, hour=t.hour) +timedelta(hours=t.minute//30)) print(now) print(hour_rounder(now)) 

Returns:

2018-02-22 23:42:43.352133 2018-02-23 00:00:00 
Sign up to request clarification or add additional context in comments.

4 Comments

hour=t.hour necessary?
@kmecpp hi there. Yes, as this function rounds the hour we need t.hour to retrieve the hour from our datetime.
But we're doing t.replace() on the original datetime. Wont it already have that hour?
@kmecpp True! But this follow the Python Zen. Explicit is better than implicit. So if we would exclude that someone might ask the opposite.
19
import pandas as pd pd.Timestamp.now().round('60min').to_pydatetime() 

Returns:

datetime.datetime(2018, 2, 23, 0, 0) 

Comments

12

This is one way.

from datetime import datetime now = datetime.now() def rounder(t): if t.minute >= 30: return t.replace(second=0, microsecond=0, minute=0, hour=t.hour+1) else: return t.replace(second=0, microsecond=0, minute=0) now # 2018-02-22 22:03:53.831589 rounder(now) # 2018-02-22 22:00:00.000000 

1 Comment

Sorry for experimenting with your solution. I rolled it back. Basically I found that it would crash when hour 23 turned hour 24. I could have changed your solution but ended up posting my own. I gave you an upvote though.
5

There is a general function to round a datetime at any time lapse in seconds here

Sample:

print roundTime(datetime.datetime(2012,12,31,23,44,59,1234),roundTo=60*60) --> 2013-01-01 00:00:00 

Comments

2

For those who need to change a whole column:

df = df['Timestamp'].dt.round('60min') 

You can also use ceil() and floor() functions to replace round, depending on the rules you want to approximate.

Comments

0

Here is one way to do it (based on another solution provided here)

def round_to_closest_hour(dttm): add_hour = True if dttm.minute >= 30 else False dttm = dttm.replace(second=0, microsecond=0, minute=0) if add_hour: dttm += timedelta(hours=1) return dttm 

Basically, check if an hour is needed to be added or not (depending on whether it's past 30 minutes mark). Then reset minutes, seconds, microseconds and add an hour if required.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.