時系列データの扱い
前回、DataFrameに格納されたデータを集計する方法をまとめた。
日時を表す項目があれば、文字列のまま扱って、groupby()させることも可能。
ただ、月、日、時、分を取り出して格納するのはイマイチ。
例えば、dateには2021-11-01、timeには15:28:01のような日付・時間を表す文字が格納されている場合、以下でdate_timeという日付型に変換できる。
iis_log6['date_time'] = pd.to_datetime(iis_log6['date'] + " " + iis_log6["time"])
日付型から時間だけ取り出す方法。
そこから、とgroupbyすれば日毎、時間帯、IPごとのカウントを取得できる。
iis_log6[ ['datet', 'hour','c-ip','time'] ].groupby(['dt','hour', 'c-ip'], as_index=False).count()
この場合、集計期間を変えるたびに別の項目を作成する必要がある。
日付型のデータで扱うことで、日・週・月・四半期など集計期間を自在に変えることができる。以下、grouperとresampleを使った方法を示す。
grouperの使い方
keyに集約したい項目、日付型の場合、期間を指定するfreqのパラメーターを指定する。
"H"は1時間単位。
iis_log6[ ['date_time','c-ip'] ].groupby(pd.Grouper(key='date_time', freq='H')).count()
とすると、1時間単位でのアクセス数が出力される。
- freqのパラメーター
D: 毎日
B: 毎営業日(月曜 - 金曜)
W: 毎週(日曜始まり)
M: 月末ごと
SM: 15日と月末ごと
Q: 四半期末ごと
AまたはY: 年末ごと
H: 毎時
Tまたはmin: 毎分
S: 毎秒
Lまたはms: 毎ミリ秒
Uまたはus: 毎マイクロ秒
N: 毎ナノ秒
日付型がインデックスの場合は、keyを省略できる。
iis_log6[ ['date_time','c-ip'] ].groupby(pd.Grouper(freq='H')).count()
resampleを使う場合
こちらの方がシンプルに記述できる。Hは日付型の期間で、on=が集計する日付型の項目(インデックスの場合は指定不要)で、grouperで指定したパラメーターと同じ。
iis_log6[ ['date_time'] ].resample('H', on='date_time').count()
こんな結果が出力される。
grouperとresampleで日付単位で、期間を指定して集計ができる。ただ、日付毎・IPアドレス毎のアクセス数、のように2段階での集計をしたい場合、どうするか?
grouperとresampleを使ってやる方法を見つけられず、groupbyでやってみた。
日付単位での項目別集計
#DataFrameの作成
log_count = iis_log6[ ['c-ip'] ]
#日付型をインデックスにセット
log_count.index=iis_log6['date_time']
#日付単位に切り上げてGroupby
log_count_byD = log_count.groupby(by=lambda x:x.floor("D"))
#c-ipをカウントして、DataFrameに変換
log_count_summary = log_count_byD['c-ip'].value_counts().to_frame()
一応、出力したい結果は出せた。
groupbyのパラメーターで、lambda関数で日付を丸めている。集計期間を変えたい場合は、日付の丸め期間を変えればOK。
grouperとresampleで出力できないのか、未だに引っ掛かります。
これくらいのことは、エクセルでやった方がスムーズなのか、と思いつつ、これらの集計結果を用いて可視化をしてみます。
つ・づ・く