ログの集計
WEBサーバーのログをDataFrameに突っ込むことはできた。これをもとにデータを集計する。
以下、IISのログを集計するPythonのコードを記述する。
groupby()による集計
ログにおける送信元IPアドレス(c-ip)の件数を表示する。
こんな集計表を出力するイメージです。
1.基本に忠実(でも、ちょっと面倒)な方法
from pandas import DataFrame
ua_df = DataFrame(iis_log6.groupby(['c-ip']).size().index)
ua_df['count'] = iis_log6.groupby(['c-ip']).size().values
2.シンプルな方法
iis_log6.groupby(['c-ip']).size().reset_index()
reset_index()をやらないと、DataFrameにならない。
iis_log6.groupby(['c-ip'], as_index=False).size()としても良さそうだけどNG。
3.count()を使用する方法
iis_log6[ ['c-ip','s-ip'] ].groupby(['c-ip'], as_index=False).count()
こちらは、as_index=Falseが機能する、
4.集約関数agg()を使う方法
iis_log6.groupby(['c-ip'])['c-ip'].agg(['size']).reset_index()
iis_log6.groupby(['c-ip']).agg(['size']).reset_index()とやると、全列に対して、sizeの値が表示される。
iis_log6'c-ip'.groupby(['c-ip']).agg(['size']).reset_index()はエラーだが、
iis_log6'c-ip','s-ip'.groupby(['c-ip']).agg(['size']).reset_index()では、一応同様の結果が得られる。
補足
iis_log6.groupby(['c-ip'], as_index=False).sum()
とすると、すべての数値フィールドにの合計をしてくれる。
ポート番号(s-port)を合計されても意味はないですが、使える場面はあるかも。
集約関数agg()の詳細
送信元IPアドレス(c-ip)別の送信バイト数 (sc-bytes)の平均(mean)、合計(sum)、最小(min)、最大(max)を表示する。
1.フィールド名を指定する方法
iis_log6.groupby('c-ip').agg( count=('c-ip', 'count'),
mean=('sc-bytes', 'mean'),
sum=('sc-bytes', 'sum'),
min=('sc-bytes', 'min'),
max=('sc-bytes', 'max')
).reset_index()
2.フィールド名を指定しない方法
iis_log6.groupby('c-ip', as_index=False).agg({'sc-bytes': ['count', 'mean','sum','min', 'max']})
フィールドの構造が二重化されます
3.可読性と再利用性を重視する方法
group_col=['c-ip']
agg_col={'sc-bytes': ['count', 'mean','sum','min', 'max']}
iis_log6.groupby(group_col).agg(agg_col).reset_index()
補足
agg()で使用されるのは、'count', 'mean','sum','min', 'max'や'std','var'など以外に、lamdaや独自関数も指定できます。その場合、Seriesが渡される。
まとめ
複数の項目でグループ化して集計したい場合は、df.groupby(['c-ip','s-ip'])とすればよく、ほとんどの集計は事足りると思われます。
残る課題は時系列データの扱いです。
つ・づ・く