昨日は Apache Pig による基本的な文法 (1)と題して Pig を触ってみましたので、今日は当然ながら基本的な文法 (2) なのかと思いきや、一昨日の記事の参考リンク先のこのあたりを見れば良いわけですから 1 回きりでなんと文法の話はおしまいです。突然の最終回です。
代わりに本日は、今まで取り扱ってきた pandas 、 R 、 Pig を使うにあたり、ある程度巨大なデータを扱うとするとどれくらい使用感が異なるか調べたいと思います。
検証対象としたデータ
次のような行の集合によって形成されたテキストファイルを考えます。キー項目は、日付、主キー、店舗名、時刻印、変換後時刻印、数値です。区切りはタブ区切りとします。
20140205 XXXXXXAABBCC Shop7 1391568621 2014-02-05 11:50:21 +0900 0
これが約 1 億行、データサイズ 7.5 ギガバイトのデータが計算機にあります。今回はこの数値のデータについて平均を求めてみます。このタスクを pandas 、 R 、 Pig で取り扱うとするとどれが一番使いか調べます。
なお検証に利用した計算機の性能は Core i7 (Haswell) 、メモリ 32GB です。
Python (pandas)
Python では pandas というデータフレーム操作用のライブラリがあります。特に制約がなければこれを使うのが良いでしょう。
$ pip install pandas
$ ipython
In [1]: import pandas as pd
In [2]: df = pd.read_table('sample.txt', header=None)
In [3]: df.ix[:,5].mean()
Out[3]: 305.4479883399822
pandas の特長は次の通りです。
- pd.read_table の時点でテキストファイルのデータがすべてメモリ上に乗る (メモリの使用量が約 8 GB 増える)
- pd.read_table の時点で待ち時間が発生する
- データフレームの操作は非常に高速
- df.ix[:,5].mean() の結果も割と高速に返る
つまり操作対象のデータをメモリに載せられるだけの性能が計算機にある場合は pandas が良いでしょう。
R
データフレームの操作と言えば R です。
df <- read.table("sample.txt", sep="\t")
colMeans(df[6])
# => V6
# 305.448
R の場合、 pandas と同様に read.table した時点でデータがメモリに載りますが、数ギガバイトのデータとなると明らかに pandas より遅い性能となりました。
また colMeans() で平均を算出しますが、統計関数も実行速度は pandas のほうに優位性がありました。
R の特長をまとめると次の通りです。
- Python の pandas と同様にデータフレーム確保のためにメモリを消費する
- 処理性能は pandas より遅い
Pig
最後に Apache Pig です。今回は単一の計算機でテキストファイルを取り扱うので pig -x local を利用します。
df = LOAD 'sample.txt' USING PigStorage('\t') AS (date: chararray, key: chararray, shop: chararray, unixtime: int, humantime: chararray, times: int);
grouped = group df all;
times_mean = foreach grouped generate AVG(df.times);
dump times_mean;
# => (305.4479883399822)
Pig の場合は LOAD 及びその後の関数を入力してもメモリは確保されません。またインタラクティブシェルも即座に応答を返します。
最後の dump times_mean; をした時点ではじめて MapReduce が実行されます。
- MapReduce でデータを処理するので一気にメモリが確保されない
- pandas や R と異なり、集計するのに複数の手順が必要となる
- 処理対象のデータに対し計算機のメモリが足りない場合は Pig に優位性がある
- また分散処理をしてデータ分析したい場合も Pig を使うことになる
まとめ
単一の計算機でデータを処理できる性能があるなら pandas 、データに対して計算機の性能が足りない場合は Pig を使うのが良いのではないかと思います。