pythonの日付列の前処理を完全攻略する

## はじめに

データ分析をしているとき、前処理でいつもやり方を忘れるのが日付型の操作です。
この記事では日付前処理でよく使う方法をまとめます。
[前処理大全](https://www.amazon.co.jp/%E5%89%8D%E5%87%A6%E7%90%86%E5%A4%A7%E5%85%A8%EF%BC%BB%E3%83%87%E3%83%BC%E3%82%BF%E5%88%86%E6%9E%90%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AESQL-R-Python%E5%AE%9F%E8%B7%B5%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF%EF%BC%BD-%E6%9C%AC%E6%A9%8B-%E6%99%BA%E5%85%89-ebook/dp/B07C3JFK3V/ref=sr_1_1?adgrpid=103835680986&dchild=1&gclid=CjwKCAjwj6SEBhAOEiwAvFRuKJdvu3eDpvcmtgfVKOH819YU6bIhnyBiTa3e6TnRUa5Zl11pIfwGUBoCNl0QAvD_BwE&hvadid=448494621272&hvdev=c&hvlocphy=1009076&hvnetw=g&hvqmt=e&hvrand=14490858679599992858&hvtargid=kwd-424362275675&hydadcr=15815_11177318&jp-ad-ap=0&keywords=%E5%89%8D%E5%87%A6%E7%90%86%E5%A4%A7%E5%85%A8&qid=1619660453&sr=8-1)の項目を参考にさせていただきました。

#データの準備
処理に用いる適当なデータを準備します

``` python:
import pandas as pd
import datetime
from datetime import timedelta
import random

#適当な日付の準備
time_list = []
time = datetime.datetime.now()
for j in range(100):
    time += timedelta(hours=4)
    time_list.append(time)

df = pd.DataFrame({"time":time_list})
df["time"] = df["time"].dt.strftime("%Y-%m-%d %H:%M:%S")
df.head()

```
こんな感じのデータができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533584/46922497-40ac-a6d4-5e83-0363c32c32e4.png)


## 日時と日付の変換
時間単位がいらない場合、年、月、日のみに変更します。

``` python:
#日時型
df["time"] = pd.to_datetime(df["time"])

#日付型
df["date"] = df["time"].dt.date
df.head()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533584/f2b05af6-609d-67d3-0681-a97b4a12c7cd.png)


## 年、月、日、時刻、分、秒、曜日への変換
年、月などそれぞれの要素を取り出します。

``` python:
#年などの取り出し
df["year"] = df["time"].dt.year
df["month"] = df["time"].dt.month
df["day"] = df["time"].dt.day
df["dayofweek"] = df["time"].dt.dayofweek
df["minute"] = df["time"].dt.minute
df["second"] = df["time"].dt.second

#指定形式への変換
df["time_tr"] = df["time"].dt.strftime("%H:%M:%S %Y-%m-%d")

df.head()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533584/aecca932-1111-216f-36c0-5b2e7b47ebcd.png)


## 年月の差分を求める
0行目の列からどのくらい時間が経過したかを計算します。
日以下の小数点は求めない場合です。

``` python:
#年と月(日以下を考慮しない)
df["year_diff"] = df["time"].dt.year - df.loc[0, "time"].year
df["month_diff"] = (df["time"].dt.year * 12 + df["time"].dt.month
                            - df.loc[0, "time"].year*12  - df.loc[0, "time"].month)

df.head()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533584/ad8167ed-f66e-2fe2-e77b-cd669ecb487a.png)


## 日、時、秒の差分を求める
自分より小さい値を小数点として表現する場合です。
例えば36時間は1.5日となります。

``` python:
#小数点以下も出すには下記
df["second_diff"] = (df["time"] - df.loc[0, "time"]).apply(lambda x:x.total_seconds())
df["minute_diff"] = df["second_diff"]/60
df["hour_diff"] = df["minute_diff"]/60
df["date_diff"] = df["hour_diff"]/24

df.head()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533584/f7f04601-7249-f992-339b-ad185dafd0da.png)



## 日時の増減

時間がずれているなどで一括で日時の増減をしたい場合です。

``` python:
from datetime import timedelta

#下記コードでそれぞれ実行可能
df["time"] + timedelta(days=1)
df["time"] + timedelta(hours=1)
df["time"] + timedelta(minutes=1)
df["time"] + timedelta(seconds=1)
```

##まとめ
差分の求め方はいつも忘れてしまいますのでこれで安心です。

)