ロード・トゥ・ザ・ホワイトハッカー

ホワイトハッカーはじめました

ログ集計(WEBサーバー編) ~数値集計~

ログの集計

WEBサーバーのログをDataFrameに突っ込むことはできた。これをもとにデータを集計する。

 

chikuwamarux.hatenablog.com

 

以下、IISのログを集計するPythonのコードを記述する。

groupby()による集計

ログにおける送信元IPアドレス(c-ip)の件数を表示する。

こんな集計表を出力するイメージです。

f:id:chikuwamaruX:20211123101823p:plain

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()

とすると、すべての数値フィールドにの合計をしてくれる。

f:id:chikuwamaruX:20211123103631p:plain

ポート番号(s-port)を合計されても意味はないですが、使える場面はあるかも。

 

集約関数agg()の詳細

送信元IPアドレス(c-ip)別の送信バイト数 (sc-bytes)の平均(mean)、合計(sum)、最小(min)、最大(max)を表示する。

f:id:chikuwamaruX:20211123104209p:plain

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']})

フィールドの構造が二重化されます

f:id:chikuwamaruX:20211126212009p:plain

 

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'])とすればよく、ほとんどの集計は事足りると思われます。

残る課題は時系列データの扱いです。

つ・づ・く