pandasのresampleを用いて急激な気温の変化を調べる

# 動機
10分間隔の気温データから，急激な気温変化を検出したい．
そこで，pandasのresampleを使うことにする．
使用するcsvファイルの中にはDateという列に観測時刻が，temperatureという列に気温データが入っている．

# resampleの使い方を確認
resampleの公式ドキュメントは[こちら](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.resample.html)．
公式ドキュメントによると，インデックスをタイムインデックスにしておく必要があるらしい．
>DataFrame.resample(rule, axis=0, closed=None, label=None, convention='start', kind=None, loffset=None, base=None, on=None, level=None, origin='start_day', offset=None, group_keys=_NoDefault.no_default)
Resample time-series data.

とりあえず`rule`にresampleしたい時間間隔を文字列で設定してあげるのが便利そう．
大文字と小文字の区別はない．
| 設定したい時間間隔 | 対応する文字列 |
|:-:|:-:|
| １年間  |  Y |
|  １ヶ月間 | M  |
|  １日間 |  D |
|  １０時間 |  10h |
|  １０分間 |  10min |
|  １０秒間 |  10s |

使用できるメソッドは`sum`, `mean`, `std`, `sem`, `max`, `min`, `median`, `first`, `last`, `ohlc`など．

## df.resample().max()
というわけで，12時間間隔で設定区間内の最大値を出力してみる．
```python:In
df = pd.read_csv(file_name)

# Date列をdatetime型のindexに設定
df['Date'] = pd.to_datetime(df['Date'])
df = df.set_index('Date')

print(df.resample('12h').max())
```
```pyhon:Out
                     temperature  
Date                                                           
2021-11-01 00:00:00          8.6                         
2021-11-01 12:00:00          5.6                         
2021-11-02 00:00:00          8.5                          
2021-11-02 12:00:00          1.4                         
2021-11-03 00:00:00          5.9                          
...                          ...
2022-04-15 00:00:00          6.8                        
2022-04-15 12:00:00          5.4                         
2022-04-16 00:00:00          2.0                          
2022-04-16 12:00:00          2.2                         
2022-04-17 00:00:00         -4.1 
```

## df.resample().apply()
最大値は得られたが，最大を記録した時間も取得したい．
しかし，調べても numpy の`argmax`や pandas の`idxmax`に相当するものがないらしい（？）．
というわけで，`apply`を用いて自作の関数で何とかする．
`apply`の公式ドキュメントは[こちら](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.resample.Resampler.apply.html)．

```python:In
# 最大値とそのインデックスを返すサブ関数を定義
def maxidx(array):
    idx = np.argmax(array)
    idx = array.index[idx]
    return [np.max(array), idx]

print(
    df['temperature'].resample('12h').apply(maxidx)
)
```
```python:Out
Date
2021-11-01 00:00:00     [8.6, 2021-11-01 10:30:00]
2021-11-01 12:00:00     [5.6, 2021-11-01 12:50:00]
2021-11-02 00:00:00     [8.5, 2021-11-02 10:40:00]
2021-11-02 12:00:00     [1.4, 2021-11-02 12:10:00]
2021-11-03 00:00:00     [5.9, 2021-11-03 11:20:00]
                                  ...             
2022-04-15 00:00:00     [6.8, 2022-04-15 09:10:00]
2022-04-15 12:00:00     [5.4, 2022-04-15 14:00:00]
2022-04-16 00:00:00     [2.0, 2022-04-16 10:30:00]
2022-04-16 12:00:00     [2.2, 2022-04-16 15:30:00]
2022-04-17 00:00:00    [-4.1, 2022-04-17 00:00:00]
Freq: 12H, Name: temperature, Length: 335, dtype: object
```

# 急激な気温変化の検出
自作の関数により，ある時間間隔ごとの気温の最大値とその観測時刻が取り出せた．
急激な気温上昇 ΔT+ と気温低下 ΔT- を調べるために，最大値と最小値が観測された時刻を比較し，最大値の方が先に観測されていれば，- (max - min)にする必要がある．
ということで，最も急激な気温変化とその変化が起こった時間間隔を返す関数を作成した．
```python:In
def calc_delta(array):
    maxidx = array.index[np.argmax(array)]
    minidx = array.index[np.argmin(array)]
    ddays = (maxidx-minidx).days
    dseconds = (maxidx-minidx).seconds
    dhours = np.round(ddays*24 + dseconds/3600, 2)
    
    if ddays>=0:
        delta = np.max(array) - np.min(array)
        start_date = maxidx
    else:
        delta = -(np.max(array) - np.min(array))
        start_date = minidx

    return [np.round(delta, 1), dhours, start_date]

print(
    df['temperature'].resample('12h').apply(calc_delta).max(axis=0), '\n',
    df['temperature'].resample('12h').apply(calc_delta).min(axis=0),
)
```
```python:Out
[19.6, 11.5, Timestamp('2022-03-04 11:50:00')] 
 [-19.5, -4.5, Timestamp('2022-04-04 19:00:00')]
```
観測期間を12時間ごとに resample し，急激な気温変化を調べた結果，
最も気温が上昇したのは，3/4 11:50 からの 11.5 時間で 19.6 ℃の上昇，
最も気温が低下したのは，4/4 19:00 からの 4.5 時間で 19.5 ℃の低下であった．