Pythonデータ分析のための実際のIPリクエストPandasの詳細な説明

高洛峰
リリース: 2017-03-24 17:08:55
オリジナル
1661 人が閲覧しました

前書き

pandas は、より高度なデータ構造とツールを含む Numpy に基づいて構築されたデータ分析パッケージであり、そのコアは ndarray ですが、pandas も Series と DataFrame の 2 つのコア データ構造を中心に展開します。 Series と DataFrame は、それぞれ 1 次元のシーケンスと 2 次元のテーブル構造に対応します。従来のpandasのインポート方法は以下の通りです:

from pandas import Series,DataFrame
import pandas as pd
ログイン後にコピー


1.1. Pandasの解析手順

1. ログデータの読み込み

2. area_ipデータの読み込み 3. real_ipリクエスト数の変更 COUNTを実行します。次の SQL に似ています:

SELECT inet_aton(l.real_ip),
  count(*),
  a.addr
FROM log AS l
INNER JOIN area_ip AS a
  ON a.start_ip_num <= inet_aton(l.real_ip)
  AND a.end_ip_num >= inet_aton(l.real_ip)
GROUP BY real_ip
ORDER BY count(*)
LIMIT 0, 100;
ログイン後にコピー

1.2. コード

cat pd_ng_log_stat.py
#!/usr/bin/env python
#-*- coding: utf-8 -*-
  
from ng_line_parser import NgLineParser
  
import pandas as pd
import socket
import struct
  
class PDNgLogStat(object):
  
  def __init__(self):
    self.ng_line_parser = NgLineParser()
  
  def _log_line_iter(self, pathes):
    """解析文件中的每一行并生成一个迭代器"""
    for path in pathes:
      with open(path, &#39;r&#39;) as f:
        for index, line in enumerate(f):
          self.ng_line_parser.parse(line)
          yield self.ng_line_parser.to_dict()
  
  def _ip2num(self, ip):
    """用于IP转化为数字"""
    ip_num = -1
    try:
      # 将IP转化成INT/LONG 数字
      ip_num = socket.ntohl(struct.unpack("I",socket.inet_aton(str(ip)))[0])
    except:
      pass
    finally:
      return ip_num
  
  def _get_addr_by_ip(self, ip):
    """通过给的IP获得地址"""
    ip_num = self._ip2num(ip)
  
    try:
      addr_df = self.ip_addr_df[(self.ip_addr_df.ip_start_num <= ip_num) &
                   (ip_num <= self.ip_addr_df.ip_end_num)]
      addr = addr_df.at[addr_df.index.tolist()[0], &#39;addr&#39;]
      return addr
    except:
      return None
            
  def load_data(self, path):
    """通过给的文件路径加载数据生成 DataFrame"""
    self.df = pd.DataFrame(self._log_line_iter(path))
  
  
  def uv_real_ip(self, top = 100):
    """统计cdn ip量"""
    group_by_cols = [&#39;real_ip&#39;] # 需要分组的列,只计算和显示该列
      
    # 直接统计次数
    url_req_grp = self.df[group_by_cols].groupby(
                   self.df[&#39;real_ip&#39;])
    return url_req_grp.agg([&#39;count&#39;])[&#39;real_ip&#39;].nlargest(top, &#39;count&#39;)
      
  def uv_real_ip_addr(self, top = 100):
    """统计real ip 地址量"""
    cnt_df = self.uv_real_ip(top)
  
    # 添加 ip 地址 列
    cnt_df.insert(len(cnt_df.columns),
           &#39;addr&#39;,
           cnt_df.index.map(self._get_addr_by_ip))
    return cnt_df
      
  def load_ip_addr(self, path):
    """加载IP"""
    cols = [&#39;id&#39;, &#39;ip_start_num&#39;, &#39;ip_end_num&#39;,
        &#39;ip_start&#39;, &#39;ip_end&#39;, &#39;addr&#39;, &#39;operator&#39;]
    self.ip_addr_df = pd.read_csv(path, sep=&#39;\t&#39;, names=cols, index_col=&#39;id&#39;)
    return self.ip_addr_df
  
def main():
  file_pathes = [&#39;www.ttmark.com.access.log&#39;]
  
  pd_ng_log_stat = PDNgLogStat()
  pd_ng_log_stat.load_data(file_pathes)
  
  # 加载 ip 地址
  area_ip_path = &#39;area_ip.csv&#39;
  pd_ng_log_stat.load_ip_addr(area_ip_path)
  
  # 统计 用户真实 IP 访问量 和 地址
  print pd_ng_log_stat.uv_real_ip_addr()
  
if __name__ == &#39;__main__&#39;:
  main()
ログイン後にコピー

実行統計と出力結果

python pd_ng_log_stat.py
  
         count  addr
real_ip           
60.191.123.80  101013 浙江省杭州市
-        32691  None
218.30.118.79  22523   北京市
......
136.243.152.18   889   德国
157.55.39.219   889   美国
66.249.65.170   888   美国
  
[100 rows x 2 columns]
ログイン後にコピー
概要

上記がこの記事の全内容です。この記事は誰にとっても役立ちます。勉強や仕事に役立ちます。質問がある場合は、メッセージを残して連絡してください。

Pythonデータ分析リアルIPリクエストPandas詳細説明関連記事の詳細については、PHP中国語Webサイトに注目してください。

関連記事:

Python の Pandas を使用して CSV ファイルを読み取り、MySQL に書き込む方法

Python の pandas ライブラリを使用した cdn ログの詳細な分析

Python の pandas フレームワークを使用して Excel でデータを操作するファイルのチュートリアル

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!