2017-09-16

【Python初心者向け】データの取得・操作・結合・グラフ化をStep by Stepでやってみる - pandas, matplotlib -



今回はデータの取得、整理、グラフ化までをすべてPythonを使ってやってみたいと思います。利用するのはPandasで、これさえあればデータの取得、整理、グラフ化までを全部行ってくれます。Step by stepで見ていきましょう。

目標物


働き方改革等、労働生産性について最近はよく議論されています。これに対して教育がどれほど関係しているのでしょうか。今回はPISAの教育データと、PISAの労働生産性データを相関分析するというシチュエーションを想定して、やってみます。
目標としては


  • 2015年度世界の労働生産性と数学学力の相関係数を取得し、散布図で示す
  • 続いて国語データを取得し、労働生産性と読解力データの散布図を示す


です。さっそくやってみましょう。

手順


  1. データの取得
    1. read_csv
  2. データの操作
    1. 必要な列だけ取得
    2. 重複する項目名の変更
    3. 条件に一致した値のみを取得する
    4. データを結合
    5. 結合したデータをCSVで保存
  3. データの描画
    1. 相関係数の取得
    2. Matplotlibで散布図を作成
  4. データの追加
    1. PISA国語データの取得
    2. 結合
    3. グラフ描画


データセット(CSV)としては以下のものを用意しました






まず最初に、pandasという計算ソフトが使えるようにします。

# 複数のCSVデータをPandasで取得
import pandas

次に、CSVがダウンロードできるページのURLをそれぞれ変数に代入します。

# GDP Per Hour Woked From OECD dataset
GDP ="https://stats.oecd.org/sdmx-json/data/DP_LIVE/.GDPHRWKD.../OECD?contentType=csv&detail=code&separator=comma&csv-lang=en"
# Mathmatics Performance From OECD dataset
MATH = "https://stats.oecd.org/sdmx-json/data/DP_LIVE/.PISAMATH.../OECD?contentType=csv&detail=code&separator=comma&csv-lang=en"

次にpandasでデータを読み取り、最初の10行を見ます。こうすることで取得したデータセットにどのような値が入っているかを確認することができます。

# pandasを利用してデータフレーム型にcsvを読み取る
GDP = pandas.read_csv(GDP) #read_csv(csv, header=None)でヘッダーなしで取得可能
MATH = pandas.read_csv(MATH)
# 最初の10行を読む(テーブルの概要が理解できる)
GDP.head()
MATH.head()

次に、2015年度のデータで比較をしたいので、2015年度のみのデータに整理します。
労働生産性に関しては、MEASUREがUSDのものだけ取得します。
MATHに関しては、SUBJECTにBOY、GIRL、TOTがあるので、TOTのみ取得します

# それぞれ2015年度と、労働生産性がUSDで測定されているデータのみをデータフレームに格納する
GDP = GDP[(GDP["TIME"] == 2015) & (GDP["MEASURE"] == "USD")]
GDP.head()
MATH = MATH[(MATH["TIME"] == 2015) & (MATH["SUBJECT"] == "TOT") ]
MATH.head()


二つのテーブルには、両方ともVALUEという値が含まれています。これだとデータを結合できません。そこで労働生産性のVALUEにはProductivity、数学テストのVALUEにはMATHという名前を付けます。

# 2つのテーブルの列名を変更し、修正結果を確認する
GDP = GDP.rename(columns={'Value': 'PRODUCTIVITY'})
GDP.head()
MATH = MATH.rename(columns={'Value': 'MATH'})
MATH.head()

今度は結合です。共通するカラムを軸に結合を行います。SQLで書くとINNER JOINみたいなかんじです。今回はお互い共通するカラムが国なので、LOCATIONで結合します。
その後お互いが同じ名前のカラムを持っていた場合、TIME_xみたいな名前になるので、修正してあげます。

# 2つのテーブルを結合する
mergedTable = pandas.merge( GDP, MATH, on = "LOCATION")
mergedTable.head()
# LOCATION, TIME, PRODUCTIVITY,  MATHのみを取得し、列名を修正する
mergedTable = mergedTable[["LOCATION", "TIME_x","PRODUCTIVITY","MATH"]]
mergedTable.rename(columns={'TIME_x': 'TIME'})
mergedTable.head()

できあがったテーブルを保存して次に再利用できるようにします。pandasのto_csvメソッドを利用して、CSVを保存します。


# 結合したテーブルを名前をつけてCSVで保存する
mergedTable.to_csv( 'GDP_AND_MATH.csv' )

さて、これでデータの下準備ができましたので、分析していきましょう。労働生産性と数学学力の関係を調べます。相関係数をcorr関数で取得します。

# 相関係数を取得する
mergedTable.head()
mergedTable.corr(method = "pearson")

相関係数は0.37と弱い相関が出てきましたね。今度はこの値をもとに散布図にデータを落とし込みます。

# 労働生産性と数学学力を散布図に落とし込む
# 縦軸・横軸に名前をつける
# 散布図にタイトルをつける
%matplotlib inline
mergedTable.plot(x = u"MATH", y = u"PRODUCTIVITY", kind = "scatter", title = "Math Achievement And Labor Productivity[R = 0.37]")






さて、これでデータの取得、整理、描画まで一通りできました。しかしもっと別のデータで検討したい場合のことを想定してみましょう。今度は読解力データをもとに分析していきたいと思います。説明は端折りますね。


#さらにPISAの国語データを取得
READING = "https://stats.oecd.org/sdmx-json/data/DP_LIVE/.PISAREAD.../OECD?contentType=csv&detail=code&separator=comma&csv-lang=en"
READING = pandas.read_csv(READING)
READING.head()
# LOCATION, VALUE, YEAR, SUBJECTだけ取得する
READING = READING[["LOCATION", "YEAR","VALUE","SUBJECT"]]
READING.head()
# YEAR = 2015, SUBJECT = "TOT"のものだけ取得する
READING = READING[(READING.TIME == 2015) & (READING.SUBJECT == "TOT")]
READING.head()

# ValueをREADINGに名前を変更する
READING = READING.rename(columns={"Value":"READING"})
READING.head()

# 元データと結合する
mergedTable = pandas.merge( mergedTable, READING, on = "LOCATION")
mergedTable.head()



# 相関係数を取得する
mergedTable.corr(method = "pearson")


(あたりまえですが数学と読解力の相関係数はかなり高いですね...
労働生産性にはあまり数学も読解力も差がないみたいです)

# グラフで描画する


mergedTable.plot(x = u"READING", y = u"PRODUCTIVITY", kind = "scatter", title = "Reading Achievement And Labor Productivity[R = 0.39]")



このへんのことはこの書籍を勉強すればできたので、おすすめです。



 参考






注目の投稿

 PythonのTweepyを利用して、Twitter APIを利用している。 その中で、ハマったポイントをメモしておく。 まず、Searchに関して。 Twitter検索は、クライアントアプリ側では、全期間の検索が可能になっている。 一方で、APIを利用する際は、過去1週間しか...