時系列データを読み込み,DatetimeIndexを持つpandas.DataFrameを作る
日付と時刻の扱い
import pandas as pd
import datetime
from dateutil.parser import parse
日付と時刻を扱うには主に[cci lang="python"]datetime.datetime[/cci]型([cci lang="python"]datetime[/cci]型と略します)を使います.日付や時刻と認識できる様々な文字列を解釈し[cci lang="python"]datetime[/cci]型に変換するのが[cci lang="python"]dateutil[/cci]パッケージの[cci lang="python"]parser.parse[/cci]メソッドです.
### 日時をdatetime型に
datetime1 = parse("2017:12:23 00:00:00")
datetime1
[cci lang="python"]datetime[/cci]型から年(文字列)を取り出すには[cci lang="python"]datetime.strftime("%Y")[/cci]とします.よく使うものをまとめると,[cci lang="python"]"%Y"[/cci]: 4桁の年,[cci lang="python"]"%m"[/cci]: 2桁の月[01,12],[cci lang="python"]"%d"[/cci]: 2桁の日[01,31],[cci lang="python"]"%H"[/cci]: 2桁の時間[00,23],[cci lang="python"]"%M"[/cci]: 2桁の分[00, 59],[cci lang="python"]"%S"[/cci]: 2桁の秒[00, 61](60と61はうるう秒を考慮),[cci lang="python"]"%z"[/cci]: UTC時間からのずれを[cci lang="python"]+HHMM[/cci]または[cci lang="python"]-HHMM[/cci]形式で表したもの,[cci lang="python"]"%F"[/cci]: [cci lang="python"]"%Y-%m-%d"[/cci]を短縮したもの(例:[cci lang="python"]"2017-1-27"[/cci]),となります.
datetime1.strftime("%Y")
[cci lang="python"]pandas[/cci]の[cci lang="python"]to_datetime[/cci]メソッドで日付時刻の文字列からなるリストを[cci lang="python"]pandas[/cci]の[cci lang="python"]DatetimeIndex[/cci]に変換でき,その1要素(あるいはスカラー)は[cci lang="python"]Timestamp[/cci]オブジェクトになります.つまり,[cci lang="python"]Timestamp[/cci]オブジェクトで構成されたリストが[cci lang="python"]datetimeIndex[/cci]です.[cci lang="python"]to_datetime[/cci]メソッドには[cci lang="python"]datetime[/cci]型を渡すこともできます.一方,[cci lang="python"]datetime.strftime[/cci]は[cci lang="python"]DatetimeIndex[/cci]や[cci lang="python"]Timestamp[/cci]には使えません.
pd.to_datetime(["2017-1-2", "2017-9-30"])
pd.to_datetime(["2017-1-2", "2017-9-30"])[0] ### 1つめの要素を抽出
pd.to_datetime(datetime1)
日付時刻をカラムに含むデータをDataFrameとして読み込み,indexをDatetimeIndexにする¶
以下のようなdataを用意します.
data={"YYYY": [1991, 1992], "MM": [2, 10], "DD": [16, 29], "HH": [2, 14], "data": [0.2, 1.7]}
pd.DataFrame(data)
辞書で作ったのでカラムの順番がdataと異なっています.カラムの順番を入れ替えます.
df=pd.DataFrame(data).loc[:,["YYYY", "MM", "DD", "HH", "data"]]
df
これをCSVファイルとして出力します.indexは削除します.
df.to_csv("data.csv", index=None)
このdata.csvを読み込みDataFrame化します.
pd.read_csv("data.csv")
年月日をインデックスにして[cci lang="python"]data.csv[/cci]を読み込みます.[cci lang="python"]parse_dates[/cci]では[cci lang="python"][[0,1,2]][/cci]と二重のカギ括弧とすることでカラム0,1,2を一つに繋げ[cci lang="python"]parse[/cci]します.
pd.read_csv("data.csv", index_col=[0,1,2], parse_dates=[[0,1,2]])
[cci lang="python"]parse_dates[/cci]にカラム名を含む辞書を渡し,そのカラム名を[cci lang="python"]index_col[/cci]に指定することもできます.
pd.read_csv("data.csv", index_col="date", parse_dates={"date":[0,1,2]})
dateとtimeを同時に読み込み,date_parser=my_parserで一気にDatetimeIndexを作る¶
しかし,時刻HHはこの方法では処理できません.[cci lang="python"]date_parser[/cci]に自前のラムダ関数[cci lang="python"]my_parser[/cci]を用意するのが一つの方法です.ただし,[cci lang="python"]index_col=[0,1,2,3][/cci]とすると[cci lang="python"]list index out of range[/cci]のエラーになります.おそらく,dateしか想定していないため,カラム数が3つまででないとだめなのではないかと推察します.[cci lang="python"]index_col="datetime"[/cci]のように[cci lang="python"]parse_dates[/cci]の辞書で指定したインデックス名を使えばうまくいきます.
ラムダ関数の引数は[cci lang="python"][0,1,2,3][/cci]を統合したものではなく,それぞれの要素です.これをy, m, d, hとすると,[cci lang="python"]fmt[/cci]と[cci lang="python"]strptime[/cci]の第一引数が整合するように両者を定義します.この方法はおそらくどのような形式でも対応できるのではないかと思います.
fmt = '%Y-%m-%d %H'
my_parser = lambda y, m, d, h: pd.datetime.strptime(y + "-" + m + "-" + d + " " + h, fmt)
pd.read_csv("data.csv", index_col="datetime", parse_dates={"datetime": [0,1,2,3]}, date_parser=my_parser)
DataFrameのカラムを結合してDatetimeIndexを作る¶
別の方法として,原始的ですが,簡単に解釈できる日付と時刻を分け,それぞれをカラムとして読み込み,後で結合してインデックス化することもできます.まず,[cci lang="python"]DataFrame df[/cci]を作ります.
df = pd.read_csv("data.csv", parse_dates=[[0,1,2]])
df
2つのカラムYYYY_MM_DD([cci lang="python"]DateTimeIndex[/cci])とHH(整数のリスト)を取り出し,リスト内包でそれぞれをx([cci lang="python"]Timestamp[/cci]), y (整数)として取り出し,[cci lang="python"]Hour(y)[/cci]で日付オフセットに変換し,両者を足し合わせた[cci lang="python"]Timestamp[/cci]を作ります.
よく使う日付オフセットは,[cci lang="python"]Hour()[/cci], [cci lang="python"]Minute()[/cci], [cci lang="python"]Second()[/cci], [cci lang="python"]Day()[/cci],です.[cci lang="python"]Hour()[/cci]は1時間,[cci lang="python"]Hour(3)[/cci]は3時間です.
from pandas.tseries.offsets import Hour ### 時間の単位である,Hourが必要です
df.index=[x + Hour(y) for x,y in zip(df['YYYY_MM_DD'],df['HH'])]
df.index.name="datetime" ### index名を設定
df
カラムを削除する¶
不要となった列の削除は[cci lang="python"]DataFrame[/cci]の[cci lang="python"]drop[/cci]メソッドを適用します.カラムが対象なので,[cci lang="python"]axis=1[/cci]が必要です.
df.drop(["YYYY_MM_DD", "HH"], axis=1)