pandasで時系列データから時刻を指定して行を抽出
pandasで時系列データ(index
がDatetimeIndex
)のpandas.DataFrame
, Series
から、特定の時刻の行を抽出するには、at_time()
およびbetween_time()
メソッドを使う。毎日の決まった時刻のデータを取り出す場合などに便利。
- pandas.DataFrame.at_time — pandas 1.2.3 documentation
- pandas.DataFrame.between_time — pandas 1.2.3 documentation
ここでは以下の内容について説明する。
- 時刻をピンポイントで指定:
at_time()
- 時間帯を指定:
between_time()
時系列データの基本については以下の記事を参照。
本記事のサンプルコードではpandas.DataFrame
のみを扱うが、pandas.Series
でも同様のメソッドが提供されている。使い方も同じ。
- pandas.Series.at_time — pandas 1.2.3 documentation
- pandas.Series.between_time — pandas 1.2.3 documentation
時刻をピンポイントで指定: at_time()
以下のpandas.DataFrame
を例とする。
import pandas as pd
import datetime
print(pd.__version__)
# 1.2.2
df = pd.DataFrame(range(6), columns=['A'],
index=pd.date_range('2021-01-01', periods=6, freq='8H'))
print(df)
# A
# 2021-01-01 00:00:00 0
# 2021-01-01 08:00:00 1
# 2021-01-01 16:00:00 2
# 2021-01-02 00:00:00 3
# 2021-01-02 08:00:00 4
# 2021-01-02 16:00:00 5
print(type(df.index))
# <class 'pandas.core.indexes.datetimes.DatetimeIndex'>
at_time()
もbetween_time()
もindex
がDatetimeIndex
である時系列データのみが対象。print()
で同じように表示されていてもindex
が文字列の場合は使えないので注意。
第一引数にdatetime.time
オブジェクトを指定すると、その時刻の行が抽出される。
print(datetime.time(8, 0, 0))
# 08:00:00
print(df.at_time(datetime.time(8, 0, 0)))
# A
# 2021-01-01 08:00:00 1
# 2021-01-02 08:00:00 4
該当データが存在しない場合は空のpandas.DataFrame
が返される。
print(df.at_time(datetime.time(12, 0, 0)))
# Empty DataFrame
# Columns: [A]
# Index: []
第一引数には時刻を表す文字列を指定することも可能。
print(df.at_time('16:00'))
# A
# 2021-01-01 16:00:00 2
# 2021-01-02 16:00:00 5
print(df.at_time('4PM'))
# A
# 2021-01-01 16:00:00 2
# 2021-01-02 16:00:00 5
時間帯を指定: between_time()
以下のpandas.DataFrame
を例とする。
df_sec = pd.DataFrame(range(6), columns=['A'],
index=pd.date_range('2021-01-01', periods=6, freq='8H5s'))
print(df_sec)
# A
# 2021-01-01 00:00:00 0
# 2021-01-01 08:00:05 1
# 2021-01-01 16:00:10 2
# 2021-01-02 00:00:15 3
# 2021-01-02 08:00:20 4
# 2021-01-02 16:00:25 5
at_time()
の場合、秒まで正確に一致していないと抽出されない。
print(df_sec.at_time('8:00'))
# Empty DataFrame
# Columns: [A]
# Index: []
print(df_sec.at_time('8:00:00'))
# Empty DataFrame
# Columns: [A]
# Index: []
print(df_sec.at_time('8:00:05'))
# A
# 2021-01-01 08:00:05 1
between_time()
を使うと、ピンポイントの時刻ではなく時間帯(幅を持った時間)を指定できる。
第一引数start_time
に開始時刻、第二引数end_time
に終了時刻を指定する。at_time()
と同様に、文字列でもdatetime.time
でも指定可能。
print(df_sec.between_time('8:00:00', '8:00:30'))
# A
# 2021-01-01 08:00:05 1
# 2021-01-02 08:00:20 4
print(df_sec.between_time(datetime.time(8, 0, 0), datetime.time(8, 0, 30)))
# A
# 2021-01-01 08:00:05 1
# 2021-01-02 08:00:20 4
start_time
がend_time
よりも後の時刻でもエラーにはならない。start_time
から24時(0時)をまわってend_time
までの時間帯のデータが抽出される。
print(df_sec.between_time('8:00:30', '8:00:00'))
# A
# 2021-01-01 00:00:00 0
# 2021-01-01 16:00:10 2
# 2021-01-02 00:00:15 3
# 2021-01-02 16:00:25 5
デフォルトではstart_time
とend_time
に指定した時刻も結果に含まれる。引数include_start
, include_end
をFalse
とすると、結果から除外される。
print(df_sec.between_time('8:00:05', '8:00:30'))
# A
# 2021-01-01 08:00:05 1
# 2021-01-02 08:00:20 4
print(df_sec.between_time('8:00:05', '8:00:30', include_start=False))
# A
# 2021-01-02 08:00:20 4