土日を除いた営業日ごとのカレンダーで考える

# 目次
1. [概要](#anchor1)
1. [営業日を調べる](#anchor2)
1. [今年の営業日カレンダーを作る](#anchor3)
1. [営業日カレンダーにデータを書き込む](#anchor4)


<a id="anchor1"></a>
# 概要
　土日を除いた月の営業日数別に時系列データを解析したい
  
<a id="anchor2"></a>

#営業日を調べる
dataの読み込み

```1.py
import pandas as pd
import numpy as np
import datetime
day_df = pd.read_pickle("mypath.pickle")
```


営業日（月曜から金曜）までの月ごとの日数を調べるクラスの作製

```2.py
class businessday(pd.core.frame.DataFrame):
    def cal_bdate_all(self):
        def cal_bdate(x):
            #月日数を7で割った商と余りを出す
            q,mod = divmod(x.day,7)
            #dayofweekは月曜が1日曜が7
            a = mod-2 if mod-x.dayofweek>2 else mod
            if x.dayofweek>5:
                return 0
            return a+q*5
        self.index.bd = self.index.map(cal_bdate)
        return self.index.bd


```

作ったクラスを適応

```3.py
bd  = businessday(day_df)
bd.cal_bdate_all()
```


用意したデータの編集と営業日の追加

```4.py
x=pd.DataFrame(columns=['month','day','%up','num'])
for a in range(1,12+1):
    for b in range(1,23+1):
        f = day_df[(day_df.index.month==a) & (bd.index.bd==b)]
        g = f['close']-f['open']
        if g.size>0:
            h= g[g>0].size/g.size
        else:
            h = -1
        tmp_se = pd.Series( [ a,b,h,g.size ], index=x.columns )
        x = x.append(tmp_se, ignore_index=True)
```
<a id="anchor3"></a>
#2021年の営業日カレンダーを作る


```5.py
calendar =  pd.date_range('2021-01-01', '2021-12-31', freq='D')

class calendar_businessday(pd.core.indexes.datetimes.DatetimeIndex):
    def cal_bdate_all(self):
        def cal_bdate(x):
            q,mod = divmod(x.day,7)
            a = mod-2 if mod-x.dayofweek>2 else mod
            if x.dayofweek>4:
                return 0
            return a+q*5
        self.bd = self.map(cal_bdate)
        return self.bd

cal = calendar_businessday(calendar)
cal.cal_bdate_all()
```

<a id="anchor4"></a>
#営業日カレンダーにデータを書き込む
カレンダーにデータを挿入

```6.py

e = pd.DataFrame(data = cal.bd,index = cal,columns=['bd'])
e['%up']  =0
e['num']  =0

for a in range(1,12+1):
    for b in range(1,23+1):
        e.loc[(e.index.bd==b) & (e.index.month==a),'%up']=x.loc[(x.day==b) & (x.month==a),'%up'].values
        e.loc[(e.index.bd==b) & (e.index.month==a),'num']=x.loc[(x.day==b) & (x.month==a),'num'].values

```

保存


```7.py
from pathlib import Path

path = "mypath"
dir = Path(path)
dir.mkdir(parents=True, exist_ok=True)
for a in range(1,12+1):
    s= path+str(a)+".pickle"
    d = path+str(a)+".csv"
    x[x.index.month==a].to_pickle(s)
    x[x.index.month==a].to_csv(d)
```

<a id="anchor5"></a>
#できたこと
カレンダーを作ってデータを挿入すること。

<a id="anchor6"></a>
#未達成なこと
今回はカレンダ―作成に年のデータが必要だったので2024年を適当に取ったがこれをなくしたい。クラスを作るか2次元配列で表すのが早そう。ただそうすると日時計算はできなくなるのが難点。まあいらないかな・・・


<a id="anchor7"></a>
#参考

[pandas.Timestamp](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Timestamp.htmlhttps://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Timestamp.html)
[Python クラスについて](https://qiita.com/motoki1990/items/376fc1d1f3d59c960f5c)
[Pythonの三項演算子（条件演算子）でif文を一行で書く](https://note.nkmk.me/python-if-conditional-expressions/)
[関数内関数](https://codor.co.jp/python/nested-function)
[pandas.Seriesのmapメソッドで列の要素を置換pandas.Seriesのmapメソッドで列の要素を置換](https://note.nkmk.me/python-pandas-map-replace/https://note.nkmk.me/python-pandas-map-replace/)
[Pandasのデータに関数を適用させるapply、applymap、mapの使い方](https://deepage.net/features/pandas-apply.htmlhttps://deepage.net/features/pandas-apply.html)
[Pythonのdivmodで割り算の商と余りを同時に取得](https://note.nkmk.me/python-divmod-quotient-remainder/)

#課題

ほぼ同じクラスを2つ作ってしまった。。。