時系列のデータを扱っていると、DataFrameの時刻情報の切り捨て・切り上げをする機会ってありますよね。この記事ではそのやり方をご紹介します。
pandas.Timestampの仕様です。
https://pandas.pydata.org/docs/reference/api/pandas.Timestamp.html
時系列の時刻データの切り捨て・切り上げ
時系列のサンプルデータは以下とします。pandas.date_range()でデータを作成し、DataFrameにしています。カラム名は”timestamp”です。
ts = pd.date_range( start='2024-11-01 10:58', end='2024-11-01 11:02', freq='min', ) df = pd.DataFrame( data=ts, columns=['timestamp'], ) print(df) # timestamp # 0 2024-11-01 10:58:00 # 1 2024-11-01 10:59:00 # 2 2024-11-01 11:00:00 # 3 2024-11-01 11:01:00 # 4 2024-11-01 11:02:00
切り捨てはfloor()で、切り上げはceil()を使います。引数でfrequencyを指定します。frequencyの単位の表を載せておきます。
Alias | 説明 |
---|---|
D | calendar day frequency |
W | weekly frequency |
MS | month start frequency |
ME | month end frequency |
h | hourly frequency |
min | minutely frequency |
s | secondly frequency |
ms | milliseconds |
us | microseconds |
ns | nanoseconds |
frequencyの詳細はこちらをご覧ください。
https://pandas.pydata.org/docs/user_guide/timeseries.html#timeseries-offset-aliases
分単位の切り捨て・切り上げはこうなります。”timestamp”カラムが処理前の時刻です。”timestamp_floor”カラムが切り捨て、”timestamp_ceil”カラムが切り上げ後の時刻です。
# 5分単位で切り捨て・切り上げ df['timestamp_floor'] = df['timestamp'].dt.floor('5min') df['timestamp_ceil'] = df['timestamp'].dt.ceil('5min') print(df) # timestamp timestamp_floor timestamp_ceil # 0 2024-11-01 10:58:00 2024-11-01 10:55:00 2024-11-01 11:00:00 # 1 2024-11-01 10:59:00 2024-11-01 10:55:00 2024-11-01 11:00:00 # 2 2024-11-01 11:00:00 2024-11-01 11:00:00 2024-11-01 11:00:00 # 3 2024-11-01 11:01:00 2024-11-01 11:00:00 2024-11-01 11:05:00 # 4 2024-11-01 11:02:00 2024-11-01 11:00:00 2024-11-01 11:05:00 # 30分単位で切り捨て・切り上げ df['timestamp_floor'] = df['timestamp'].dt.floor('30min') df['timestamp_ceil'] = df['timestamp'].dt.ceil('30min') print(df) # timestamp timestamp_floor timestamp_ceil # 0 2024-11-01 10:58:00 2024-11-01 10:30:00 2024-11-01 11:00:00 # 1 2024-11-01 10:59:00 2024-11-01 10:30:00 2024-11-01 11:00:00 # 2 2024-11-01 11:00:00 2024-11-01 11:00:00 2024-11-01 11:00:00 # 3 2024-11-01 11:01:00 2024-11-01 11:00:00 2024-11-01 11:30:00 # 4 2024-11-01 11:02:00 2024-11-01 11:00:00 2024-11-01 11:30:00
時間単位の切り捨て・切り上げです。
# 1時間単位で切り捨て・切り上げ df['timestamp_floor'] = df['timestamp'].dt.floor('1h') df['timestamp_ceil'] = df['timestamp'].dt.ceil('1h') print(df) # timestamp timestamp_floor timestamp_ceil # 0 2024-11-01 10:58:00 2024-11-01 10:00:00 2024-11-01 11:00:00 # 1 2024-11-01 10:59:00 2024-11-01 10:00:00 2024-11-01 11:00:00 # 2 2024-11-01 11:00:00 2024-11-01 11:00:00 2024-11-01 11:00:00 # 3 2024-11-01 11:01:00 2024-11-01 11:00:00 2024-11-01 12:00:00 # 4 2024-11-01 11:02:00 2024-11-01 11:00:00 2024-11-01 12:00:00 # 3時間単位で切り捨て・切り上げ df['timestamp_floor'] = df['timestamp'].dt.floor('3h') df['timestamp_ceil'] = df['timestamp'].dt.ceil('3h') print(df) # timestamp timestamp_floor timestamp_ceil # 0 2024-11-01 10:58:00 2024-11-01 09:00:00 2024-11-01 12:00:00 # 1 2024-11-01 10:59:00 2024-11-01 09:00:00 2024-11-01 12:00:00 # 2 2024-11-01 11:00:00 2024-11-01 09:00:00 2024-11-01 12:00:00 # 3 2024-11-01 11:01:00 2024-11-01 09:00:00 2024-11-01 12:00:00 # 4 2024-11-01 11:02:00 2024-11-01 09:00:00 2024-11-01 12:00:00
日単位の切り捨て・切り上げです。
1日単位で切り捨て・切り上げ df['timestamp_floor'] = df['timestamp'].dt.floor('D') df['timestamp_ceil'] = df['timestamp'].dt.ceil('D') print(df) # timestamp timestamp_floor timestamp_ceil # 0 2024-11-01 10:58:00 2024-11-01 2024-11-02 # 1 2024-11-01 10:59:00 2024-11-01 2024-11-02 # 2 2024-11-01 11:00:00 2024-11-01 2024-11-02 # 3 2024-11-01 11:01:00 2024-11-01 2024-11-02 # 4 2024-11-01 11:02:00 2024-11-01 2024-11-02
単一の時刻データの切り捨て・切り上げ
単一の時刻のデータは以下のように作成します。
t = pd.Timestamp('2024-11-01 10:28') print(t) print(type(t)) # 2024-11-01 10:28:00 # <class 'pandas._libs.tslibs.timestamps.Timestamp'>
切り捨てはfloor()で、切り上げはceil()で、引数でfrequencyを指定します。
# 切り捨て t = pd.Timestamp('2024-11-01 10:28') print(t.floor('15min')) print(t.floor('1h')) print(t.floor('D')) # 2024-11-01 10:15:00 # 2024-11-01 10:00:00 # 2024-11-01 00:00:00 # 切り上げ t = pd.Timestamp('2024-11-01 10:28') print(t.ceil('15min')) print(t.ceil('1h')) print(t.ceil('D')) # 2024-11-01 10:30:00 # 2024-11-01 11:00:00 # 2024-11-02 00:00:00
補足ですが、round()で四捨五入もできます。
# 四捨五入 t = pd.Timestamp('2024-11-01 10:28') print(t.round('15min')) print(t.round('1h')) print(t.round('D')) # 2024-11-01 10:30:00 # 2024-11-01 10:00:00 # 2024-11-01 00:00:00 t = pd.Timestamp('2024-11-01 11:32') print(t.round('15min')) print(t.round('1h')) print(t.round('D')) # 2024-11-01 11:30:00 # 2024-11-01 12:00:00 # 2024-11-01 00:00:00