1
0

More than 1 year has passed since last update.

pandasのdatetime計算でハマった件

Last updated at Posted at 2021-09-30

本記事は私がハマった2件を検証した内容となっておりますが、初歩的ミスだったので
最終的に「そうだよねー」となる結論になっております。

1. datetimeの差分を取得する際

取り扱ってる研究用時間データはまぁまぁ膨大なので仮の日付を用いてかつ以下のように記述してあります(※再現性重視)

test.py
import pandas as pd

a = '2200/04/01 23:00:05'
b = '2200/04/08 23:00:00'

df = pd.DataFrame([a,b],index=['A', 'B'], columns=['date'])
df['date'] = pd.to_datetime(df['date'])
B,A = df['date'].max(), df['date'].min()

(B - A).days #result: 6 

あれ。4/8 と4/1って日の差が1週間だからresult: 7が出力されて欲しかったんだけど... ん?と思い検証。

1.の修正

結論としては「秒単位で計算してるっぽい」
だって計算結果表示したらこうだもの。

(B - A)  #result: Timedelta('6 days 23:59:55')

勝手にday属性だけ取得して減算してると思ってました...
そりゃもっと正確な値を出してきますよねーって感じでした。

modify.py
(B.day - A.day) #result: 7

2. DataFrameから特定期間を抽出する際

テストデータ作成
test_dates = []
for d in range(1,11):
    for h in range(24):
        test_dates.append(f'2200/01/{d} {h}:00')

date_df = pd.DataFrame(test_dates, columns=['date'])
date_df['date'] = pd.to_datetime(date_df['date'])

date_df
date
2200/01/01 00:00
2200/01/01 01:00
...
2200/01/10 22:00
2200/01/10 23:00

1/1から1/8のデータを取得したい場合
こんな書き方で期間を抽出するんですが、この時起きた問題

件のコード
date_df[(datetime.datetime(2200,1,1) <= date_df['date'])&(date_df['date'] <= datetime.datetime(2200,1,8))]
date
2200/01/01 00:00
2200/01/01 01:00
...
2200/01/07 23:00
2200/01/08 00:00

となってしまう問題
(空白はpep8に則っていないけれど見やすさ重視)

直感的にはこう書きそうなものなんだけれど、1/8のデータが欠けてしまっている。

2.の修正

datetime.datetime(2200,01,09)と記述するとそりゃ省略されてるのは00:00となっている様子。
つまり<= datetime.datetime(2020,01,09)<= 2200/01/09 00:00ということらしい。
そりゃそうなりますよね。

modify.py
start_date = datetime.datetime(2200,1,1)

#case 1:愚直に 次の日の24時ギリギリまで取得
end_date = datetime.datetime(2200,1,9)
date_df[(start_date <= date_df['date'])&(date_df['date'] < end_date)]

#case 2: 一日分追加っていう明示的なやり方?(case 1 の方が楽ですね)
end_date = datetime.datetime(2200,1,8)
one_day = datetime.timedelta(days=1)
date_df[(start_date <= date_df['date'])&(date_df['date'] < end_date + one_day)]

参考記事

1
0
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
1
0