本記事は私がハマった2件を検証した内容となっておりますが、初歩的ミスだったので
最終的に「そうだよねー」となる結論になっております。
1. datetimeの差分を取得する際
取り扱ってる研究用時間データはまぁまぁ膨大なので仮の日付を用いてかつ以下のように記述してあります(※再現性重視)
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属性だけ取得して減算してると思ってました...
そりゃもっと正確な値を出してきますよねーって感じでした。
(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
ということらしい。
そりゃそうなりますよね。
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)]