【Python】PandasのDataFrameで、毎日・毎時間などの時系列のindexを作る方法（pandas.date_range）

## 背景
- `Pandas`の`DataFrame`の時系列データを取り扱っている際に、毎日や毎時間といった`datetime`型の`index`が必要になることがあります。
- 時系列の`index`は`str`型で作成してしまうこともありますが、データの抽出や加工のことを考えるとしっかりと`datetime`型の`index`を使いたいというニーズがあると思います。
- [pandas.date_range](https://pandas.pydata.org/docs/reference/api/pandas.date_range.html)を使用すれば簡単に作成できるので作成方法を紹介します。

## 目標
- `Pandas`の`datetime`型の`index`を自在に作成できるようになる。

## [pandas.date_range](https://pandas.pydata.org/docs/reference/api/pandas.date_range.html)を使用し、datetime型のindexを持つDataFrameを作成する方法
- [pandas.date_range](https://pandas.pydata.org/docs/reference/api/pandas.date_range.html)の使い方は簡単で、以下のように、`start`と`end`に`index`を作成したい期間を指定するだけで、等差の`datetime`型の`index`が作成されます。

```python:毎日（date）のDatetimeIndexを作成する。（期間指定）
import pandas as pd
import numpy as np

#毎日（date）のDatetimeIndexを作成する。（期間指定）
date_index = pd.date_range(start='2023-01-01', end='2023-01-05')

print(date_index)
#DatetimeIndex(['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04',
#               '2023-01-05'],
#              dtype='datetime64[ns]', freq='D')
```
- 上記で作成した、`DatetimeIndex`を`index`に指定して`df`を作成します。

```python:上記で作成した、DatetimeIndexをindexに指定してdfを作成する。
#上記で作成した、DatetimeIndexをindexに指定してdfを作成する。
df = pd.DataFrame(np.arange(5).reshape(5, 1), columns = ['data'], index = date_index)

print(df)
#                     data
#2023-01-01 00:00:00     0
#2023-01-01 06:00:00     1
#2023-01-01 12:00:00     2
#2023-01-01 18:00:00     3
#2023-01-02 00:00:00     4
```

- 作成した`df`の`index`が`DatetimeIndex`となっているかを確認します。

```python:dfのindexがDatetimeIndexになっているか確認する。
#dfのindexがDatetimeIndexになっているか確認する。
print(df.info())
#<class 'pandas.core.frame.DataFrame'>
#DatetimeIndex: 5 entries, 2018-01-01 to 2018-01-05
#Freq: D
#Data columns (total 1 columns):
# #   Column  Non-Null Count  Dtype
#---  ------  --------------  -----
# 0   data    5 non-null      int64
#dtypes: int64(1)
#memory usage: 80.0 bytes
```

## その他[pandas.date_range](https://pandas.pydata.org/docs/reference/api/pandas.date_range.html)の様々な使い方

### 毎日（`date`）の`DatetimeIndex`を作成（`index`の作成個数指定：前から）
```python:毎日（date）のDatetimeIndexを作成する。（indexの作成個数指定：前から）
#毎日（date）のDatetimeIndexを作成する。（indexの作成個数指定：前から）
date_index = pd.date_range(start='2023-01-01', periods=8)

print(date_index)
# DatetimeIndex(['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04',
#                '2023-01-05', '2023-01-06', '2023-01-07', '2023-01-08'],
#               dtype='datetime64[ns]', freq='D')
```

### 毎日（`date`）の`DatetimeIndex`を作成（`index`の作成個数指定：後ろから）
```python:毎日（date）のDatetimeIndexを作成する。（indexの作成個数指定：後ろから）
#毎日（date）のDatetimeIndexを作成する。（indexの作成個数指定：後ろから）
date_index = pd.date_range(end='2023-01-01', periods=8)

print(date_index)
# DatetimeIndex(['2022-12-25', '2022-12-26', '2022-12-27', '2022-12-28',
#                '2022-12-29', '2022-12-30', '2022-12-31', '2023-01-01'],
#               dtype='datetime64[ns]', freq='D')
```

### タイムゾーン（`tz`）を追加した`index`の作成

```python:タイムゾーン（tz）を追加したindexを作成する。
#タイムゾーン（tz）を追加したindexを作成する。
date_index = pd.date_range(start='2023-01-01', periods=8, tz='Asia/Tokyo')

print(date_index)
# DatetimeIndex(['2023-01-01 00:00:00+09:00', '2023-01-02 00:00:00+09:00',
#                '2023-01-03 00:00:00+09:00', '2023-01-04 00:00:00+09:00',
#                '2023-01-05 00:00:00+09:00', '2023-01-06 00:00:00+09:00',
#                '2023-01-07 00:00:00+09:00', '2023-01-08 00:00:00+09:00'],
#               dtype='datetime64[ns, Asia/Tokyo]', freq='D')
```

### 指定期間を等分に分割した時刻の`index`の作成

```python:指定期間を等分に分割した時刻のindexを作成する。
#指定期間を等分に分割した時刻のindexを作成する。
date_index = pd.date_range(start='2023-01-01', end='2023-01-02', periods=5)

print(date_index)
# DatetimeIndex(['2023-01-01 00:00:00', '2023-01-01 06:00:00',
#                '2023-01-01 12:00:00', '2023-01-01 18:00:00',
#                '2023-01-02 00:00:00'],
#               dtype='datetime64[ns]', freq=None)
```

### 指定時刻から指定個数の時間を等差時間で増加する`index`の作成

```python:指定時刻から指定個数の時間を等差時間で増加するindexを作成する。
#指定時刻から指定個数の時間を等差時間で増加するindexを作成する。
#1ヶ月ごと（M）
date_index = pd.date_range(start='2023-01-01', periods=5, freq='M')

print(date_index)
# DatetimeIndex(['2023-01-31', '2023-02-28', '2023-03-31', '2023-04-30',
#                '2023-05-31'],
#               dtype='datetime64[ns]', freq='M')

#1日ごと（D）
date_index = pd.date_range(start='2023-01-01', periods=5, freq='D')

print(date_index)
# DatetimeIndex(['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04',
#                '2023-01-05'],
#               dtype='datetime64[ns]', freq='D')

#1時間ごと（h）
date_index = pd.date_range(start='2023-01-01', periods=5, freq='h')

print(date_index)
# DatetimeIndex(['2023-01-01 00:00:00', '2023-01-01 01:00:00',
#                '2023-01-01 02:00:00', '2023-01-01 03:00:00',
#                '2023-01-01 04:00:00'],
#               dtype='datetime64[ns]', freq='H')

#1分ごと（min）
date_index = pd.date_range(start='2023-01-01', periods=5, freq='min')

print(date_index)
# DatetimeIndex(['2023-01-01 00:00:00', '2023-01-01 00:01:00',
#                '2023-01-01 00:02:00', '2023-01-01 00:03:00',
#                '2023-01-01 00:04:00'],
#               dtype='datetime64[ns]', freq='T')

#1秒ごと（s）
date_index = pd.date_range(start='2023-01-01', periods=5, freq='s')

print(date_index)
# DatetimeIndex(['2023-01-01 00:00:00', '2023-01-01 00:00:01',
#                '2023-01-01 00:00:02', '2023-01-01 00:00:03',
#                '2023-01-01 00:00:04'],
#               dtype='datetime64[ns]', freq='S')
```

## 参考資料
https://pandas.pydata.org/docs/reference/api/pandas.date_range.html

## 個人ブログ

https://takuma-tech.com/2023/01/18/379/