見出し画像

10行でセ・パ両リーグの球団成績をスクレイピングして可視化する

割引あり

早くも前半戦が終わりました。
今回は球団の成績をセ・パ両リーグスクレイピングしてマージします。
マージした後そのデータを使って簡単に可視化します。


1. インポート

使用するライブラリをインポートします。
スクレイピングで使用するライブラリはpandasです。
可視化にはmatplotlibとseabornを使用します。
In [14]:

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

2. データ取得

プロ野球フリークにあるデータをスクレイピングさせていただきます。
df_bに野手の球団別成績、df_pに投手の球団別成績が取得されます。
In [15]:

df_b = pd.read_html('https://baseball-data.com/team/hitter.html')
df_p = pd.read_html('https://baseball-data.com/team/pitcher.html')

3. データ結合

取得したデータはリスト形式になっています。
0番地にセ・リーグ。1番地にパ・リーグのデータが格納されているので、野手成績が入っているdf_bと投手成績をdf_pをpd.mergeで結合します。
結合するキーは、野手成績にも投手成績にも共通してある列全てをキーにします。
結合の仕方は内部結合にします。
centralにセ・リーグの球団の成績を、pacificにパ・リーグの球団成績が入りました。
In [16]:

central = pd.merge(df_b[0],df_p[0],on=['順 位','チーム','試 合','勝 利','敗 北','引 分'],how='inner')
pacific = pd.merge(df_b[1],df_p[1],on=['順 位','チーム','試 合','勝 利','敗 北','引 分'],how='inner')

4. 列追加

リーグが区別できるようにリーグ列を作って、セ・リーグには「セ」、パリーグには「パ」を入れます。
In [17]:

central['リーグ'] = 'セ'
pacific['リーグ'] = 'パ'

5. データ縦結合

teamsにpd.concatでセ・リーグとパ・リーグのデータ縦結合して一つのデータフレーム形式にします。
In [18]:

teams = pd.concat([central,pacific],axis=0)

6. データ出力

最後にcsv形式に出力します。
In [19]:

teams.to_csv('team_data.csv')

7. 可視化関数

可視化関数はseabornを使って散布図と近似線(直線、曲線含む)をプロットする関数作成します。
seabornの関数を都度使っていっても良いですが、複数の列があるデータのためいろんな組み合わせのプロットを作りたい場合には、
関数にして可視化したい列、色分けしたい列を指定すればグラフにできるようにすると便利です。
In [41]:

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

def plotting(data,x,y,hue=None,order=1,fname='test.png',tname='チーム'):
    sns.lmplot(data=data, x=x, y=y,hue=hue,order=order)
    for x, y, name in zip(data[x],data[y],data[tname]):
        plt.text(x, y, name)
    plt.grid()
    plt.savefig(fname)

関数にしておくと、列を変えたり、ファイル名を変えたり、色分けそする場合としない場合でプロットを変えるときに数行のコードを何度も書く必要がなくなります。
In [45]:

plotting(teams,'打 率','防 御 率',order=1,tname='チーム')
plotting(teams,'打 率','勝 利',tname='チーム',fname='rank_plot.png',hue='リーグ')

8. 可視化関数の解説

可視化関数のplottingは5行のコードをひとまとめにしています。
引数は7種類と多めですが、初期データを入力しておくことで最低でも、dataとxとyの3種類を入力すれば実行できるようにしておきます。
dataにはデータフレーム形式のデータをいれます。 
xはx軸にするデータ列、yにはy軸にするデータ列を指定します。
hueは色分けするためのどの種類のデータ列で区別するかを指定します。
指定しなければ、色分けしないグラフになります。
orderは近似線の次数を指定します。
何も設定しなければ直線近似をするために1が入ります。
2次の近似曲線にしたい場合は2を、3次の近似曲線3を指定します。
fnameはグラフの画像保存する際のファイル名を入力します。
入力しない場合はtest.pngのファイル名で出力されます。
tnameは散布図のグラフの点にテキスト出力するデータ列を指定します。
初期設定にはおそらくよく表示するテキストであろうチームを最初から指定しています。
2行目のsns.lmplot(data=data, x=x, y=y,hue=hue,order=order)で散布図と近似線をプロットします。
3〜4行目のfor文処理で散布図の点にテキスト表示します。
5行目のplt.grid()はメモリ線を描画するための処理です。
6行目の最後にプロットしたグラフを保存する関数のplt.savefig()で画像保存します。
これで、引数をだけ指定してあげればplottingでグラフ表示して保存することができます。

9. 本記事のプログラム

今回のプログラムをまとめると以下のようになります。
スクレイピング部分はメインメソッドに書いています。
スクレイピング部分だけであれば10行のコードで実現できます。
plotting関数で散布図+近似線のグラフを描く処理を作っています。
seabornの描画関数はさまざまなものがありますので、別のグラフ用の関数を作ったりしてみると良いでしょう。
In [ ]:

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

def plotting(data,x,y,hue=None,order=1,fname='test.png',tname='チーム'):
    sns.lmplot(data=data, x=x, y=y,hue=hue,order=order)
    for x, y, name in zip(data[x],data[y],data[tname]):
        plt.text(x, y, name)
    plt.grid()
    plt.savefig(fname)import pandas as pd

if __name__ == "__main__":
    df_b = pd.read_html('https://baseball-data.com/team/hitter.html')
    df_p = pd.read_html('https://baseball-data.com/team/pitcher.html')
    central = pd.merge(df_b[0],df_p[0],on=['順 位','チーム','試 合','勝 利','敗 北','引 分'],how='inner')
    pacific = pd.merge(df_b[1],df_p[1],on=['順 位','チーム','試 合','勝 利','敗 北','引 分'],how='inner')
    central['リーグ'] = 'セ'
    pacific['リーグ'] = 'パ'
    teams = pd.concat([central,pacific],axis=0)
    teams.to_csv('team_data.csv')
    plotting(teams,'打 率','防 御 率',order=1,tname='チーム')
    plotting(teams,'打 率','勝 利',tname='チーム',fname='rank_plot.png',hue='リーグ')

10. まとめ

本記事では、10行で球団別成績をスクレイピングして取得したデータを可視化するプログラムを紹介しました。
データの取得が意外と簡単にできることを実感できたのであれば幸いです。
グラフの描画に関しては散布図と近似線のプロット関数を作成しました。
グラフに関してはさまざまな種類があるので自身が作りたいグラフは関数で自作するのが良いでしょう。
実際に関数にして作ると勉強になりますのでお勧めします。

本記事のプログラムを購入したい方はこちら。

本記事のコードは有料記事を購入することができます。
9.本記事のプログラムのコードをコピペすれば、そのまま利用することができます。

ここから先は

0字 / 2ファイル
この記事のみ ¥ 100〜
期間限定 PayPay支払いすると抽選でお得に!

よろしければサポートをよろしくお願いします。サポートいただいた資金は活動費に使わせていただきます。