読者です 読者をやめる 読者になる 読者になる

Gunosyデータ分析ブログ

Gunosyで働くデータエンジニアが知見を共有するブログです。

【初心者向け】Jupyter+Pandas+matplotlibを使ったデータ分析入門

こんにちは、データ分析部でバイトをしている子田(id:woody_kawagoe)です。

ニュースパスのログを集計して分析するといった業務を行っています。Gunosyで分析に利用しているツールとしては主にJupyter, Pandas, matplotlibがあります。 この組み合わせは非常に相性が良く、研究でも役立つと思います。 そこで今回のブログではデータ分析に役立つtipsや学んだことをまとめます。

Jupyter

jupyter.org

ブラウザ上で利用できる開発環境です。 対話型で、作成したスクリプトと出力結果の対応関係が非常に見やすいです。 スクリプトでprint文をかかなくても最終行に変数おけば表示してくれます。 またgithub上にJupyterで作成できるipynbファイルを置くと他のユーザからでもJupyterと同様のUIで確認出来ます。 そのためipynbファイルをそのまま解析結果の資料として職場が学校で報告することが可能です。

これは僕がJupyterで作成したコードです。 データ分析ではなく自然言語処理100本ノックの第1章の解答ですが、出力結果と合わせて見ることができて見やすいかと思います。

github.com

またvimを使う人にとっても親切なことに、Jupyter上でvimが使える拡張機能が公開されています。 以下のリンクを参考に設定してみてください。

qiita.com

Pandas

Python Data Analysis Library — pandas: Python Data Analysis Library

pythonで利用できるデータ分析用ライブラリです。 表形式のデータをSQLやRのように操作し、高速で処理できて便利です。

Pandasで扱うデータ型としてDataFrameとSeriesがあります。 DataFrameは複数の列を持ち、Seriesは1列のみのデータ型です。 DataFrameから1列を抽出した場合も勝手にSeriesになります。 この2つの型で使用できるメソッドが異なる場合があるので注意が必要です。

以下、pythonの対話モードでの実行例です。

>>> import pandas as pd
>>> df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('ABCD'))
>>> df
'''
          A         B         C         D
0  0.563617  2.232149  0.246438 -1.582011
1 -0.865735 -0.092077 -1.117475 -0.832390
2  0.464084 -0.713113 -0.859806  1.683599
3 -0.569110 -0.343353 -0.054545  0.380017
4  0.232089  1.577586 -0.550634  1.990078
5  0.436252 -0.293231 -0.033918  0.738073
'''
>>> type(df)
'''
<class 'pandas.core.frame.DataFrame'>
'''
>>> df.A
'''
0    0.563617
1   -0.865735
2    0.464084
3   -0.569110
4    0.232089
5    0.436252
'''
>>> type(df.A)
'''
<class 'pandas.core.series.Series'>
'''

例えばvalue_counts()というユニークな値の個数をカウントするというメソッドがあります。 よく利用されるメソッドですが、Seriesのみでしか使えません。

df['E'] = ['one', 'one','two','three','four','three']
>>> df
'''
          A         B         C         D      E
0  0.563617  2.232149  0.246438 -1.582011    one
1 -0.865735 -0.092077 -1.117475 -0.832390    one
2  0.464084 -0.713113 -0.859806  1.683599    two
3 -0.569110 -0.343353 -0.054545  0.380017  three
4  0.232089  1.577586 -0.550634  1.990078   four
5  0.436252 -0.293231 -0.033918  0.738073  three
'''
>>> df.E.value_counts()
'''
three    2
one      2
four     1
two      1
Name: E, dtype: int64
'''
>>> df.value_counts()
'''
(中略)
AttributeError: 'DataFrame' object has no attribute 'value_counts'
'''

よく使うメソッドとしてgroupby()があります。これはSQLのGROUPBY文に似ています。 ユニークにしたいカラム(複数でも可)を指定し、その後に集計関数(sum(),max()など)をつけると他カラムの集計結果を返します。

>>> df.groupby('E').sum()
'''
              A         B         C         D
E                                            
four   0.232089  1.577586 -0.550634  1.990078
one   -0.302118  2.140072 -0.871037 -2.414401
three -0.132858 -0.636584 -0.088463  1.118090
two    0.464084 -0.713113 -0.859806  1.683599
'''
>>> df.groupby('E').max()
'''
              A         B         C         D
E                                            
four   0.232089  1.577586 -0.550634  1.990078
one    0.563617  2.232149  0.246438 -0.832390
three  0.436252 -0.293231 -0.033918  0.738073
two    0.464084 -0.713113 -0.859806  1.683599
'''

またDataFrameは自分で中身を作らなくてもread_csv()でCSVファイルを読み込んだり、 read_sql_query()を使ってSQLをDBに送って作成することもできます。

matplotlab

matplotlib: python plotting — Matplotlib 1.5.3 documentation

pythonのデータ可視化ライブラリです。 PandasのDataFrameを元にプロットができ、出力したグラフはそのままJupyter上に表示されます。 最低plot()をDataFrame型かSeries型につければグラフの表示が出来ます。

以下、Jupyter上での実装例です。

import pandas as pd
import numpy as np 
import matplotlib.pyplot as plt
%pylab inline --no-import-all

ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
ts = ts.cumsum() # 各要素に直前のデータと合計した値を格納する、つまり累計する
ts.plot()

f:id:woody_kawagoe:20161220152909p:plain

スタイルをggplotにしておく良い感じの見た目になります。

plt.style.use('ggplot') 
ts.plot()

f:id:woody_kawagoe:20161220152917p:plain

plot内のオプションを変更することでグラフの設定を変更できます。 試しにヒストグラムを表示してみます。

ts.plot(kind='hist')

f:id:woody_kawagoe:20161220153645p:plain

データ分析の基本的な流れ

データ分析の基本的な流れは以下のような形になります。

1. SQLを飛ばしてデータを取得

2. Pandasでガチャガチャいじる

3. matplotlibでグラフ出力

f:id:woody_kawagoe:20161226110148p:plain

それぞれの処理について詳しく説明します。

1.SQLを飛ばしてデータを取得

まずPandasのread_sql_query()を使ってDBから大まかなデータを集計してDataFrameを作ります。 Pandasをほとんど使わなくてもSQLで十分データを整形できるというパターンもあるかもしれませんが、 一回クエリを送って取得したデータを繰り返し使うということが多いです。 理由としては何度もクエリを送ると時間がかかってしまったり、 DBに負荷を与えてしまう可能性があるためです。 余談ですが僕は上司に「重いクエリ投げたら(そのクエリを)すぐ殺すから安心して」と言われて一瞬ビビったことがあります。 SQLとPandasのどちらに力をいれるかはケースバイケースですが、 データサイズが大きい程クエリの回数は少なくすべきかと思います。 解析対象がCSVファイルの場合はread_csv()を使ってDataFrameを作ります。

2.Pandasでガチャガチャいじる

先ほどのDataFrameを様々な方法で整形します。 場合によってはそのまま表を結果として表示することもあります。 グラフ出力したい場合もここで中身を確認しつつ解析するのが良いと思います。

またSeries型をそのままJupyter上で出力するとテキストのみの表示になってしまうのですが、 pd.DataFrame(<Series型の変数>)と無理矢理DataFrameに変えて出力すると表形式で表示されて見やすいです。

3.matplotlibでグラフ出力

整形したDataFrameをグラフにします。 ただ全体をプロットしてもいいですが、特徴的な部分をplt.xlim()plt.ylim()で範囲指定した方が見やすい場合もあります。 他にもpltのメソッドで色々指定ができるので見やすく整形しましょう。

参考資料

Pythonによるデータ分析入門 https://www.amazon.co.jp/Pythonによるデータ分析入門-―NumPy、pandasを使ったデータ処理-Wes-McKinney/dp/4873116554www.amazon.co.jp

今回紹介したツールについて詳しく解説している本です。Pandasについて解説している書籍は少ないようで、Pandasを学びたい人に役立つ一冊となりそうです。

10 Minutes to pandas(英語) 10 Minutes to pandas — pandas 0.19.2 documentation

Pandasの公式サイトにある解説ページです。たぶん10分じゃ終わらないと思いますが、役立つ機能が1ページにまとまっていてわかりやすいです。