内容
jpholidayというライブラリがあって、日付を渡すと祝日かどうか教えてくれます。
特徴量として、平日か祝日かみたいなことを考えるときに、月~金のうち祝日を主に取り出したいって感じ
import jpholiday
from datetime import date
today = date.today()
print(today)
print(jpholiday.is_holiday(today))
# 2020-12-09
# False
こんな感じで。
ただ、何となくpandasでぶちこむと残念ながらうまくいきません
import pandas as pd
from datetime import date, timedelta
today = date.today()
date_time = []
for i in range(1000):
for _ in range(1000):
date_time.append(today + timedelta(days = i))
df = pd.DataFrame({
'datetime': date_time
})
print(df.head())
datetime
0 2020-12-09
1 2020-12-09
2 2020-12-09
3 2020-12-09
4 2020-12-09
このdfのdatetime列について投入すると
jpholiday.is_holiday(df.datetime)
...
AttributeError: 'Series' object has no attribute 'month'
できないので、こうするとできます
df.datetime.map(jpholiday.is_holiday)
しかし、列数が100万超えてくるデータセットだとこの作業でも時間がかかります。
import time
import logging
from contextlib import contextmanager
@contextmanager
def timer(name, logger=None, level=logging.DEBUG):
print_ = print if logger is None else lambda msg: logger.log(level, msg)
t0 = time.time()
print_(f'[{name}] start')
yield
print_(f'[{name}] done in {time.time() - t0:.1f} s')
with timer("map"):
df.datetime.map(jpholiday.is_holiday)
[map] start
[map] done in 54.4 s
遅い。多分mapが1行ずつやってるからと思われます
そこで、unique()で重複している列を消して、dict形式でmapします
with timer("make_map"):
dates = df.datetime.unique()
date_dict = {}
for i in dates:
date_dict[i] = jpholiday.is_holiday(pd.to_datetime(i))
df.datetime.map(date_dict)
[make_map] start
[make_map] done in 0.3 s
for文でもそれなりに早くなった
内包表記にするともうちょっと早くなるかも
要するに
このスクリプトはデータが1日1件しかない場合は使えません。
今回のデータ定義みたいに、1日に1000件が1000日みたいなときに早くできます。
参考になれば幸いです。