9
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[python3][pandas]時間でroundを使う際の細かい話

Last updated at Posted at 2022-12-02

pyhton3のdt.round

時間を指定した区切りに丸めることができる。

rng = pd.date_range('1/1/2018 11:59:00', periods=3, freq='min')

print(rng)
print(rng.round('H')) # 'H':時間で丸める

"""出力
DatetimeIndex(['2018-01-01 11:59:00', '2018-01-01 12:00:00',
               '2018-01-01 12:01:00'],
              dtype='datetime64[ns]', freq='T')
DatetimeIndex(['2018-01-01 12:00:00', '2018-01-01 12:00:00',
               '2018-01-01 12:00:00'],
              dtype='datetime64[ns]', freq=None)
"""

ドキュメント

やること

このdt.round(時間の丸め)を使う際に入力時間を細かくして確認したときに
想定と違う動作をしたので、それについてアウトプットする。

実行環境

windows 11
python 3.10.5
pandas 1.5.1

使い方

import pandas as pd
df_date = pd.DataFrame({'初期': ['2022-11-26 12:07:30', '2022-11-26 12:07:31']})
df_date['初期'] = pd.to_datetime(df_date['初期']) # 文字列をdatetimeに変換する
df_date['round'] = df_date['初期'].dt.round("15T")
print(df_date)

""" 出力
                   初期               round
0 2022-11-26 12:07:30 2022-11-26 12:00:00
1 2022-11-26 12:07:31 2022-11-26 12:15:00
"""

round("15T")で15分丸めを指定した場合
半分である7分30秒を基準時間として出力が
「切り上げ、切り捨て」と変化する

入力時間を細かく変えて確認

15分丸め

df_time = pd.DataFrame(pd.date_range(start='2022-01-01 12:07:00', periods=60, freq="1S", name="初期"))

# 半分を基準に切り上げ、切り捨てする
df_time['round'] = df_time['初期'].dt.round("15T")

print(df_time)
df_time.to_csv("time_round.csv")

丸め時間を「15分、30分、45分、00分」と変化するように
入力データ(1秒ごとの時間データ)を生成して確認すると
image.png

丸め時間によって切り替わる基準時間が
30秒と31秒に分かれる。

10分丸め

roundは「偶数に丸めようとする」

というのがあるので、丸め時間を10分(偶数)にすると
切り替わる基準時間が同じになると想定し試すと
image.png
基準時間が1秒と0秒と別れ、想定通りにならなかったが
15分丸めと同じように「切り上げ、切り捨て」を繰り替えしているのがわかる

1分丸め

さらに細かくしても「切り上げ、切り捨て」を繰り替えす
image.png

見えてきた法則

x(=1)分区切りの時

  1. 丸め時間の半分が基準時間となるx分/2(=30秒)の
  2. 「x(=1)分、3x(=3)分、5x(=5)分・・・」の時の基準時間は切り捨て(奇数のような動作?)
  3. 「0分、2x(=2)分、4x(=4)分・・・」の時の基準時間は切り上げ(偶数のような動作?)

3のように「丸め時間の2倍」を「偶数」のように扱い、
基準時間の時に「偶数」側に近づくように丸める

丸め基準時間を固定するには

「時間で判定して切り上げ、切り捨て」というように
処理を自分で書くしかなさそう

丸め基準時間固定の1分区切り

def df_time_round(df_datetimes):
    # 引数のDataFrameをコピー
    return_df_datetimes = df_datetimes.copy()
    for index, time in enumerate(df_datetimes):
        # 30秒以下の場合
        if time.second <= 30:
            # 1分区切りの切り捨て
            return_df_datetimes[index] = time.floor(freq='1T')
        # 31秒以上の場合
        else:
            # 1分区切りの切り上げ
            return_df_datetimes[index] = time.ceil(freq='1T')
    
    return return_df_datetimes

minute_num = 1
df_time = pd.DataFrame(pd.date_range(start='2022-01-01 12:' + str(minute_num) + ':00', periods=60, freq="1S", name="initial"))

# 関数で処理した結果を返し、csvに出力
df_time["new_round"] = df_time_round(df_time['initial'])
df_time.to_csv("time_round1_" + str(minute_num) + ".csv")

image.png
基準時間の31秒になると繰り上げとなるようにできた!

まとめ

細かい話で確認や推測を立てるのが大変だが
分析すると法則が見えてくるなと思いました。

9
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?