pandasのreindexとdate_rangeを利用して、時系列データの欠損を埋める

ECサイトの売上のデータ解析などをしていると、休日のデータが欠損している場合がある。 解析時には日付が欠損していると不便なことがあるので、0などのある値で埋めるために、pandasのreindexとdate_rangeを利用する。

github

  • githubのjupyter notebook形式のファイルはこちら

google colaboratory

  • google colaboratory で実行する場合はこちら

実行環境

!sw_vers
ProductName:	macOS
ProductVersion:	11.6.7
BuildVersion:	20G630
!python -V
Python 3.8.13

時系列データでデータの穴抜けがあるDataFrameを用意する。

import pandas as pd

df = pd.DataFrame({
    'sales': [i + 1 for i in range(5)],
    'date': pd.to_datetime(['2022-07-01', '2022-07-02', '2022-07-05', '2022-07-06', '2022-07-09'])
})
df
salesdate
012022-07-01
122022-07-02
232022-07-05
342022-07-06
452022-07-09
土日が休みや定休日があるお店だとよく見られるデータである
時系列データで日付に穴があると解析時に不便な場合があるのでこれを埋める事が今回の目的である

date_range

pandasにはdate_rangeという連続的な日次のデータを作成してくれる関数がある。 startとendを設定し、frequencyを指定するだけである。 freqに60minを設定すると1時間毎に、240minを指定すると4時間毎のdatetime型のlistを作ることができる。

pd.date_range('2022-07-01', '2022-07-02', freq='60min')
DatetimeIndex(['2022-07-01 00:00:00', '2022-07-01 01:00:00',
               '2022-07-01 02:00:00', '2022-07-01 03:00:00',
               '2022-07-01 04:00:00', '2022-07-01 05:00:00',
               '2022-07-01 06:00:00', '2022-07-01 07:00:00',
               '2022-07-01 08:00:00', '2022-07-01 09:00:00',
               '2022-07-01 10:00:00', '2022-07-01 11:00:00',
               '2022-07-01 12:00:00', '2022-07-01 13:00:00',
               '2022-07-01 14:00:00', '2022-07-01 15:00:00',
               '2022-07-01 16:00:00', '2022-07-01 17:00:00',
               '2022-07-01 18:00:00', '2022-07-01 19:00:00',
               '2022-07-01 20:00:00', '2022-07-01 21:00:00',
               '2022-07-01 22:00:00', '2022-07-01 23:00:00',
               '2022-07-02 00:00:00'],
              dtype='datetime64[ns]', freq='60T')
pd.date_range('2022-07-01', '2022-07-02', freq='240min')
DatetimeIndex(['2022-07-01 00:00:00', '2022-07-01 04:00:00',
               '2022-07-01 08:00:00', '2022-07-01 12:00:00',
               '2022-07-01 16:00:00', '2022-07-01 20:00:00',
               '2022-07-02 00:00:00'],
              dtype='datetime64[ns]', freq='240T')

reindex

date_rangeとreindexを利用して、欠損データの穴埋めをする。 reindexは設定されいるindexに値があるときはその値が割り振られ、値がない場合はNaNが割り振られる。 ただ、穴埋めするデータもfill_valueで指定することができる。今回は0で埋める。

start_time = df['date'].tolist()[0]
end_time = df['date'].tolist()[-1]

time_list = pd.date_range(start_time, end_time, freq='1d')
df.set_index('date').reindex(time_list, fill_value=0)
sales
2022-07-011
2022-07-022
2022-07-030
2022-07-040
2022-07-053
2022-07-064
2022-07-070
2022-07-080
2022-07-095

7/3や7/4などの欠損データが0で穴埋めされている。

意味がないが、reindexの引数のlistに応じてデータを並び替えることができるので、time_list[::-1]とすると、順序を逆にすることができる。

df.set_index('date').reindex(time_list[::-1], fill_value=0)
sales
2022-07-095
2022-07-080
2022-07-070
2022-07-064
2022-07-053
2022-07-040
2022-07-030
2022-07-022
2022-07-011

date_rangeもreindexも使用頻度は高くないので、忘れないようにする。