note.nkmk.me

pandasで時系列データから時刻を指定して行を抽出

Posted: 2021-04-01 / Tags: Python, pandas, 時系列データ

pandasで時系列データ(indexDatetimeIndex)のpandas.DataFrame, Seriesから、特定の時刻の行を抽出するには、at_time()およびbetween_time()メソッドを使う。毎日の決まった時刻のデータを取り出す場合などに便利。

ここでは以下の内容について説明する。

  • 時刻をピンポイントで指定: at_time()
  • 時間帯を指定: between_time()

時系列データの基本については以下の記事を参照。

本記事のサンプルコードではpandas.DataFrameのみを扱うが、pandas.Seriesでも同様のメソッドが提供されている。使い方も同じ。

スポンサーリンク

時刻をピンポイントで指定: 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()indexDatetimeIndexである時系列データのみが対象。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_timeend_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_timeend_timeに指定した時刻も結果に含まれる。引数include_start, include_endFalseとすると、結果から除外される。

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
スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事