本記事での目的
とあるデータ分析での前処理に必要になった際にざっと調べても出てこなかったのでここで共有します。要は、str
をpd.datetime64[ns]
に変換したうえでデータを連番にしてあげればいいです。
- 変換前
- 変換後
実装する
まず、文字列から~
を区切りと分割して新しいカラムとして用意します。カラム名は後で削除するので、わかりやすい名称であれば何でもいいです。西暦はデータによりますが、ここでは2021年としました。
import pandas as pd
from datetime import datetime
# 分割する
df["first"] = df["datetime"].apply(lambda x: "2021/"+x.split("~")[0])
df["last"] = df["datetime"].apply(lambda x: "2021/"+x.split("~")[1])
形式を整形しつつ、pd.datetime
型に変換。
# 年/月/日
df["first"] = df['first'].apply(lambda _: datetime.strptime(_,"%Y/%m/%d"))
df["last"] = df['last'].apply(lambda _: datetime.strptime(_,"%Y/%m/%d"))
# ここでdatetime変換
df["first"] = pd.to_datetime(df["first"])
df["last"] = pd.to_datetime(df["last"])
最後に系列順になるように縦に結合します。大雑把に説明するとデータの分だけループさせて最初のデータフレームを基に下にくっつけていくイメージです。より汎用的な方法もあるかもしれません。
for i, (f, e) in enumerate(zip(df["first"].tolist(), df["last"].tolist())):
# 日付を連番で作成
date = pd.date_range(start=f, end=e)
if i == 0:
# 一番最初だけ変数で保持しておいて縦に結合していく
df1 = pd.DataFrame({"a": df.loc[i, "a"], "b": df.loc[i, "b"]}, index=date)
else:
df2 = pd.DataFrame({"a": df.loc[i, "a"], "b": df.loc[i, "b"]}, index=date)
# データを結合してから変数に上書きする
df1 = pd.concat([df1, df2])
# インデックス名を定義
df1.index.name = "datetime"
df1
最後に
データ分析の際のざっとした確認になれば幸いです。