Pig を使う
昨日は主に Apache Pig を使うまでの準備について書きました。今日から Pig のスクリプトを記述して実際にデータを分析していくところを説明していきます。
インタラクティブシェルを起動する
Ruby で言う irb や pry 、 Python で言う ipython のように、 Pig でもインタラクティブシェルを起動して挙動を確認することができます。
pig -x local
このようにインタラクティブシェルを起動して挙動を確認するのはインタプリタ言語の基本ですね。 C-r がうまく機能しないなど若干足りない面もありますがひとまずこれで Pig を対話的に動かすことができます。
データの形式を定義して読み込む
次のようなデータを考えます。
20140312 XXXXXXF6XXXX Shop7 1394560015 2014-03-12 02:46:55 +0900 0
20140312 XXXXXXC2XXXX Shop1 1394560104 2014-03-12 02:48:24 +0900 0
20140312 XXXXXXF6XXXX Shop8 1394559936 2014-03-12 02:45:36 +0900 0
20140312 XXXXXXF6XXXX Shop8 1394560009 2014-03-12 02:46:49 +0900 73
20140312 XXXXXXF6XXXX Shop8 1394560050 2014-03-12 02:47:30 +0900 41
20140312 XXXXXXF6XXXX Shop3 1394560111 2014-03-12 02:48:31 +0900 61
20140312 XXXXXXF6XXXX Shop8 1394560199 2014-03-12 02:49:59 +0900 88
20140312 XXXXXX56XXXX Shop16 1394560009 2014-03-12 02:46:49 +0900 0
20140312 XXXXXXAEXXXX Shop16 1394559933 2014-03-12 02:45:33 +0900 0
20140312 XXXXXXAEXXXX Shop16 1394559996 2014-03-12 02:46:36 +0900 63
R でも python (pandas) でもカンマあるいはタブ区切りのデータを読み込むためには専用の関数が用意されていました。 Pig でも同じでまずはデータを読み込んで利用可能にします。
raw = LOAD 'input.txt' USING PigStorage('\t') AS (date: chararray, key: chararray, shop: chararray, unixtime: int, humantime: chararray, times: int);
int, long, float, double といったお馴染みの数値型、文字型については chararray が使えます。
データを参照する
データの中身は dump で参照できます。インタラクティブシェルで最も頻繁に使う命令かもしれません。
dump raw;
データを集約する
特定の条件でデータをまとめるには GROUP を使います。たとえば上の例のデータをキー毎にまとめてみます。
grouped = GROUP raw BY key;
XXXXXX00XXXX {(20140312,XXXXXX00XXXX,Shop12,1394560172,2014-03-12 02:49:32 +0900,0),(20140312,XXXXXX00XXXX,Shop10,1394560123,2014-03-12 02:48:43 +0900,8),(20140312,XXXXXX00XXXX,Shop11,1394560134,2014-03-12 02:48:54 +0900,11),(20140312,XXXXXX00XXXX,Shop11,1394560136,2014-03-12 02:48:56 +0900,2),(20140312,XXXXXX00XXXX,Shop10,1394560154,2014-03-12 02:49:14 +0900,18),(20140312,XXXXXX00XXXX,Shop11,1394560172,2014-03-12 02:49:32 +0900,18),(20140312,XXXXXX00XXXX,Shop8,1394560016,2014-03-12 02:46:56 +0900,0),(20140312,XXXXXX00XXXX,Shop11,1394560111,2014-03-12 02:48:31 +0900,0),(20140312,XXXXXX00XXXX,Shop12,1394560115,2014-03-12 02:48:35 +0900,4),(20140312,XXXXXX00XXXX,Shop8,1394560076,2014-03-12 02:47:56 +0900,60),(20140312,XXXXXX00XXXX,Shop8,1394560136,2014-03-12 02:48:56 +0900,60),(20140312,XXXXXX00XXXX,Shop1,1394560196,2014-03-12 02:49:56 +0900,60)}
XXXXXX01XXXX {(20140312,XXXXXX01XXXX,Shop13,1394559983,2014-03-12 02:46:23 +0900,0),(20140312,XXXXXX01XXXX,Shop14,1394559986,2014-03-12 02:46:26 +0900,3),(20140312,XXXXXX01XXXX,Shop12,1394559983,2014-03-12 02:46:23 +0900,0)}
...
データを数える
上の出力結果のタプルとなったデータをカウントしてみます。これは先程とは逆で、まとめたデータを展開する形になります。
counted = FOREACH grouped GENERATE flatten($1);
(20140312,XXXXXX00XXXX,Shop12,1394560172,2014-03-12 02:49:32 +0900,0)
(20140312,XXXXXX00XXXX,Shop10,1394560123,2014-03-12 02:48:43 +0900,8)
(20140312,XXXXXX00XXXX,Shop11,1394560134,2014-03-12 02:48:54 +0900,11)
(20140312,XXXXXX00XXXX,Shop11,1394560136,2014-03-12 02:48:56 +0900,2)
(20140312,XXXXXX00XXXX,Shop10,1394560154,2014-03-12 02:49:14 +0900,18)
(20140312,XXXXXX00XXXX,Shop11,1394560172,2014-03-12 02:49:32 +0900,18)
(20140312,XXXXXX00XXXX,Shop8,1394560016,2014-03-12 02:46:56 +0900,0)
(20140312,XXXXXX00XXXX,Shop11,1394560111,2014-03-12 02:48:31 +0900,0)
(20140312,XXXXXX00XXXX,Shop12,1394560115,2014-03-12 02:48:35 +0900,4)
(20140312,XXXXXX00XXXX,Shop8,1394560076,2014-03-12 02:47:56 +0900,60)
(20140312,XXXXXX00XXXX,Shop8,1394560136,2014-03-12 02:48:56 +0900,60)
(20140312,XXXXXX00XXXX,Shop1,1394560196,2014-03-12 02:49:56 +0900,60)
(20140312,XXXXXX01XXXX,Shop13,1394559983,2014-03-12 02:46:23 +0900,0)
...
データを取り除く
今度は times が 60 以下のデータを取り除いてみましょう。このように特定のデータを除外する場合は FILTER が使えます。
filtered = FILTER raw BY times > 60;
(20140312,XXXXXXF6XXXX,Shop8,1394560009,2014-03-12 02:46:49 +0900,73)
(20140312,XXXXXXF6XXXX,Shop3,1394560111,2014-03-12 02:48:31 +0900,61)
(20140312,XXXXXXF6XXXX,Shop8,1394560199,2014-03-12 02:49:59 +0900,88)
(20140312,XXXXXXAEXXXX,Shop16,1394559996,2014-03-12 02:46:36 +0900,63)
(20140312,XXXXXXAEXXXX,Shop16,1394560059,2014-03-12 02:47:39 +0900,63)
(20140312,XXXXXXAEXXXX,Shop16,1394560122,2014-03-12 02:48:42 +0900,63)
(20140312,XXXXXXAEXXXX,Shop16,1394560185,2014-03-12 02:49:45 +0900,63)
(20140312,XXXXXXA7XXXX,Shop2,1394560042,2014-03-12 02:47:22 +0900,67)
(20140312,XXXXXX72XXXX,Shop16,1394560005,2014-03-12 02:46:45 +0900,66)
(20140312,XXXXXX72XXXX,Shop16,1394560073,2014-03-12 02:47:53 +0900,68)
(20140312,XXXXXX72XXXX,Shop16,1394560139,2014-03-12 02:48:59 +0900,66)
...
どうやら無事に抽出できたようですね。
データをファイルに出力する
ファイルに出力するには STORE を使います。
STORE filtered INTO 'result' USING PigStorage();
まとめ
今回は対話的に Pig のシェルを操作して最も基本的なデータのハンドリングを試してみました。