Python
pandas

(個人メモ)python 日付などをkey にした集計

More than 1 year has passed since last update.

Apacheログからの集計で日付毎の集計はよくやるのですが、ピーク時間帯だけを抽出して日付単位に合計と推移を評価したいなんてことが良くあります。

Apacheログ→Pandasでread_csv時にParseするわけなのですが、フォーマットは%Y-%m-%d %H:%M:%Sで列に入っていて日付と時間を分離するのもちょっとめんどくさい話になります。日付抽出はfloor('24h')などを使って時間部分を切り捨てればなんとかなりますが、時間部分だけ分離するのは少々苦労します。

結局断念しました。

で、なにか他の方法がないか探ったら・・いいやつがありました。
以下サンプルコードです。Pandas便利です。

import pandas as pd
import datetime
import  numpy as np
rng = pd.date_range(start = '2014-01-01',periods = 100, freq='H')
df_original = pd.DataFrame({'Volume' : np.ranpdom.randint(100,2000,len(rng))}, index=rng)
df_original.head()

データはこんな感じで生成します。
これをつかって演算。

Volume
2014-01-01 00:00:00 790
2014-01-01 01:00:00 423
2014-01-01 02:00:00 197
2014-01-01 03:00:00 509
2014-01-01 04:00:00 1214
2014-01-01 05:00:00 826
2014-01-01 06:00:00 706
2014-01-01 07:00:00 1098
2014-01-01 08:00:00 126

... ...
2014-01-04 16:00:00 1668
2014-01-04 17:00:00 1422
2014-01-04 18:00:00 354
2014-01-04 19:00:00 1683
2014-01-04 20:00:00 1364
2014-01-04 21:00:00 1218
2014-01-04 22:00:00 1250
2014-01-04 23:00:00 552
2014-01-05 00:00:00 302
2014-01-05 01:00:00 814
2014-01-05 02:00:00 802
2014-01-05 03:00:00 874

9時〜11時のデータを日をまたいで抽出します。串刺しのイメージ。

# 縦串(日付をまたいで)時間範囲抽出
from datetime import time
df_original.loc[time(9, 0):time(11, 0)]

# こちらでもOK
df_original.between_time(time(9, 0),time(11, 0))

Volume
2014-01-01 09:00:00 1644
2014-01-01 10:00:00 540
2014-01-01 11:00:00 1217
2014-01-02 09:00:00 1671
2014-01-02 10:00:00 846
2014-01-02 11:00:00 460
2014-01-03 09:00:00 155
2014-01-03 10:00:00 1741
2014-01-03 11:00:00 1918
2014-01-04 09:00:00 937
2014-01-04 10:00:00 966
2014-01-04 11:00:00 398

これはすごい・・・ちゃんと日付を通じて特定時間帯データを抽出出来てます。

さらに時間帯抽出結果を日別集計。

df_original.between_time(time(9, 0),time(11, 0)).resample('D').mean()

バッチリ出来てます。

Volume
2014-01-01 1133.666667
2014-01-02 992.333333
2014-01-03 1271.333333
2014-01-04 767.000000

もちろん「日付」列など作らなくとも日毎の集計も簡単です。

# 日単位で算出
df_original.resample('D').mean()

Volume
2014-01-01 1030.083333
2014-01-02 1025.291667
2014-01-03 1094.875000
2014-01-04 1086.833333
2014-01-05 970.750000

これは捗る!!