Pandas Timestamp округляет 30 секунд непоследовательно - PullRequest
4 голосов
/ 17 июня 2019

Я пытаюсь округлить панды DatetimeIndex (или Timestamp) до ближайшей минуты, но у меня проблема с метками времени в 30 секунд - некоторые округляются вверх, некоторые округляются вниз (кажется, чередуются).

Любые предложения, чтобы исправить это, чтобы 30-е всегда округлились?

>>> pd.Timestamp(2019,6,1,6,57,30).round('1T')
Timestamp('2019-06-01 06:58:00')

>>> pd.Timestamp(2019,6,1,6,58,30).round('1T')
Timestamp('2019-06-01 06:58:00')

Лучший результат выглядит неплохо: 57 м 30 с округлением до 58 м, но я ожидаю, что нижний результат округлит до 59 м, а не до 58 м.

Ответы [ 2 ]

6 голосов
/ 17 июня 2019

Это ceil раунд

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')

Обновление, это десятичная проблема

from decimal import Decimal, ROUND_HALF_UP
s=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')
3 голосов
/ 17 июня 2019

Округление является последовательным; Затем следует выбор: «когда на полпути между двумя целыми числами выбрано четное целое число». Вы хотите округлить до половины, что вам нужно реализовать самостоятельно.

import numpy as np
import pandas as pd

def 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 Data
df = pd.DataFrame({'date': pd.date_range('2019-01-01', freq='15S', periods=10)})
df['rounded'] = half_up_minute(df.date)

Выход:

                 date             rounded
0 2019-01-01 00:00:00 2019-01-01 00:00:00
1 2019-01-01 00:00:15 2019-01-01 00:00:00
2 2019-01-01 00:00:30 2019-01-01 00:01:00
3 2019-01-01 00:00:45 2019-01-01 00:01:00
4 2019-01-01 00:01:00 2019-01-01 00:01:00
5 2019-01-01 00:01:15 2019-01-01 00:01:00
6 2019-01-01 00:01:30 2019-01-01 00:02:00
7 2019-01-01 00:01:45 2019-01-01 00:02:00
8 2019-01-01 00:02:00 2019-01-01 00:02:00
9 2019-01-01 00:02:15 2019-01-01 00:02:00
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...