Pandas Timestamp rounds 30 seconds inconsistently Pandas Timestamp rounds 30 seconds inconsistently pandas pandas

Pandas Timestamp rounds 30 seconds inconsistently


This is ceil round

pd.Timestamp(2019,6,1,6,57,30).ceil('1T')Out[344]: Timestamp('2019-06-01 06:58:00')pd.Timestamp(2019,6,1,6,58,30).ceil('1T')Out[345]: Timestamp('2019-06-01 06:59:00')

Update , this is decimal problem

from decimal import Decimal, ROUND_HALF_UPs=Decimal((pd.Timestamp(2019,6,1,6,58,30).value//60)/1e9).quantize(0, ROUND_HALF_UP)pd.to_datetime(int(s)*60*1e9)Out[28]: Timestamp('2019-06-01 06:59:00')s=Decimal((pd.Timestamp(2019,6,1,6,57,30).value//60)/1e9).quantize(0, ROUND_HALF_UP)pd.to_datetime(int(s)*60*1e9)Out[30]: Timestamp('2019-06-01 06:58:00')


The rounding is consistent; the choice followed is, "when halfway between two integers the even integer is chosen." You want half-up rounding, which you will need to implement yourself.

import numpy as npimport pandas as pddef half_up_minute(x):    m = (x - x.dt.floor('1T')).dt.total_seconds() < 30   # Round True Down, False Up    return x.where(m).dt.floor('1T').fillna(x.dt.ceil('1T'))# For indices:def half_up_minute_idx(idx):    m = (idx - idx.floor('1T')).total_seconds() < 30   # Round True Down, False Up    return pd.Index(np.select([m], [idx.floor('1T')], default=idx.ceil('1T')))# Sample Datadf = pd.DataFrame({'date': pd.date_range('2019-01-01', freq='15S', periods=10)})df['rounded'] = half_up_minute(df.date)

Output:

                 date             rounded0 2019-01-01 00:00:00 2019-01-01 00:00:001 2019-01-01 00:00:15 2019-01-01 00:00:002 2019-01-01 00:00:30 2019-01-01 00:01:003 2019-01-01 00:00:45 2019-01-01 00:01:004 2019-01-01 00:01:00 2019-01-01 00:01:005 2019-01-01 00:01:15 2019-01-01 00:01:006 2019-01-01 00:01:30 2019-01-01 00:02:007 2019-01-01 00:01:45 2019-01-01 00:02:008 2019-01-01 00:02:00 2019-01-01 00:02:009 2019-01-01 00:02:15 2019-01-01 00:02:00