競馬予想のためのPandas入門

スクレイピング

 

・スクレイピングでできることは分かったけど、具体的に何から始めればいいのか分からない。

 

そんな方に向けて、出馬表のデータをまるっと取り込む方法をお伝えします。

予想もWebスクレイピングも出馬表が出発点。

一度、出馬表をWebスクレイピングしてみることで、データの取得対象や加工など、ご自身がやりたいことの道筋が見えてきます。

 

この記事では、PythonのライブラリであるPandasを使って、出馬表からデータ取得 → CSVファイルに出力するところまでを説明します。

 

 

1.Pandasとは

Pandasとは、Pythonのライブラリのひとつでデータ分析によく使われます。

列と行で構成されたデータの整理や分析が得意で、データの追加や編集、数値計算も可能です。Microsoftのエクセルをイメージしてもらえると分かりやすいと思います。

 

・SeriesとDataFrame

Pandasを理解するうえで必要な知識として、SeriesとDataFrameがあります。ここではこの2つについて説明します。

Pandasでは主に、一次元、二次元の配列で構成されたデータを取り扱います。

配列とは、同じ分類のデータのまとまりです。(少なくともこの記事では、この考え方で問題ありません。)

 

例えば、馬体重という分類があって、個々の馬のデータがひとまとまりになっているところをイメージしてもらうと、わかりやすいと思います。

このようなデータ構造を一次元配列といい、PandasではSeriesと呼びます。

馬体重を例にコードを書くと以下のようになります。

※コードの説明はコメントを参照して下さい。

 

import pandas as pd  #Pandasを呼び出し

bataijuu = pd.Series([462, 518, 440])  #bataijuuに一次配列の馬体重データを3つ格納

print(bataijuu)  #格納したデータを表示

#実行結果
0    462
1    518
2    440
dtype: int64

 

 

実行結果で表示されている左端の縦の数字をIndex(インデクス)と呼び、各データと関連付けされています。

ただ、実際は他の分類も関連付けされていることが多いと思います。

例えば馬名が追加されたケースだと以下のような感じになります。

 

import pandas as pd

df = pd.DataFrame([['uma1', 462],['uma2', 518],['uma3', 440]],columns =['馬名','馬体重'])

print(df) #格納したデータを表示

#実行結果
     馬名  馬体重
0  uma1  462
1  uma2  518
2  uma3  440
dtype: int64

 

「馬名+馬体重」のようにSeriesを複数を持つデータ構造を二次元配列といい、PandasではDataFrameと呼びます。

DataFrameでは、横軸のデータの分類をColumn(カラム)と呼びます。

 

 

2.準備

Pandasでできることと、SeriesとDataFrameの説明が完了しました。

このPandasの基礎を押さえておけば、実際の作業も理解できるはずです。

 

なので、さっさとPandasをインストールしましょう。

以下を実行し、「Successfully installed ~」と表示されれば成功です。

 

py -m pip install pandas

 

 

Python全般の準備がまだの方は、以下を参考に環境構築から始めましょう。

競馬予想のためのWebスクレイピング入門

 

 

3.実際にデータを取り込む

準備ができたら実際にデータを取り込んでみましょう。対象データは本サイトの出馬表サンプルを使います。

以下のコードを実行してみてください。出馬表のデータが取り込めていることが分かると思います。

 

出馬表サンプル

 

import pandas as pd

url = 'http://umano-ie.com/racesample/' #取得対象ページのURLを格納

df = pd.read_html(url) #対象ページの表を取得

print(df[0]) #取得データを表示

#実行結果
   0   1     2   3     4     5       6        7      8   9
0  枠  馬番  馬名  性齢    斤量    騎手      厩舎      馬体重    オッズ  人気
1  1   1    ラジャーバローズ  牡3  55.0    真中   角井(栗)  486(-8)   34.0   6
2  2   2    ワゲネリアン  牡3  55.0    福長   智道(栗)  450(-2)    9.5   4
3  3   3    レイドオロ  牡3  55.0  ロメーロ  富士澤(美)  480(-4)   13.7   5
4  4   4    ムカヒキ  牡3  55.0   河和田   智道(栗)  502(+4)    2.3   1
5  5   5    デラメンテ  牡3  55.0  D.ムロ   堀井(美)  484(-2)    5.4   3
6  6   6    ワンアンドオイリー  牡3  55.0    横乗   橋田(栗)  482(+4)  118.7   8
7  7   7    クサリ  牡3  55.0    竹豊   佐木(栗)  478(-2)   43.5   7
8  8   8    ディープゲリランテ  牡3  55.0   磐田康   小木(栗)  496(-6)    2.4   2

 

 

4.不要なデータを削除する

データを取得するときに、あらかじめ不要なデータが決まっているなら削除しましょう。

このときdropメソッドを使用します。

※メソッドについては、場を改めて説明します。ここではPandasのなかで使えるツールくらいに記憶してください。

 

特定のColumnを削除するときは、以下のように書きます。例では騎手データを削除しています。

 

import pandas as pd

url = 'http://umano-ie.com/racesample/'
df = pd.read_html(url)

df[0]= df[0].drop(df[0].columns[[5]], axis=1) #dropメソッドでColumnの5番目(=騎手)を削除

print(df[0])

#実行結果
   0   1     2   3     4       6        7      8   9
0  枠  馬番  馬名  性齢    斤量      厩舎      馬体重    オッズ  人気
1  1   1    ラジャーバローズ  牡3  55.0   角井(栗)  486(-8)   34.0   6
2  2   2    ワゲネリアン  牡3  55.0   智道(栗)  450(-2)    9.5   4
3  3   3    レイドオロ  牡3  55.0  富士澤(美)  480(-4)   13.7   5
4  4   4    ムカヒキ  牡3  55.0   智道(栗)  502(+4)    2.3   1
5  5   5    デラメンテ  牡3  55.0   堀井(美)  484(-2)    5.4   3
6  6   6    ワンアンドオイリー  牡3  55.0   橋田(栗)  482(+4)  118.7   8
7  7   7    クサリ  牡3  55.0   佐木(栗)  478(-2)   43.5   7
8  8   8    ディープゲリランテ  牡3  55.0   小木(栗)  496(-6)    2.4   2

 

 

Indexを削除したい場合は以下のとおりです。

 

import pandas as pd

url = 'http://umano-ie.com/racesample/'
df = pd.read_html(url)

df[0]= df[0].drop(df[0].index[[5]]) #dropメソッドでIndexの5番目(=デラメンテ)を削除

print(df[0])

#実行結果
   0   1     2   3     4     5       6        7      8   9
0  枠  馬番  馬名  性齢    斤量    騎手      厩舎      馬体重    オッズ  人気
1  1   1    ラジャーバローズ  牡3  55.0    真中   角井(栗)  486(-8)   34.0   6
2  2   2    ワゲネリアン  牡3  55.0    福長   智道(栗)  450(-2)    9.5   4
3  3   3    レイドオロ  牡3  55.0  ロメーロ  富士澤(美)  480(-4)   13.7   5
4  4   4    ムカヒキ  牡3  55.0   河和田   智道(栗)  502(+4)    2.3   1
6  6   6    ワンアンドオイリー  牡3  55.0    横乗   橋田(栗)  482(+4)  118.7   8
7  7   7    クサリ  牡3  55.0    竹豊   佐木(栗)  478(-2)   43.5   7
8  8   8    ディープゲリランテ  牡3  55.0   磐田康   小木(栗)  496(-6)    2.4   2

 

 

お気づきの方もいるかと思いますが、Columnが数字になっており、Indexの0番目に本来はColumnにあって欲しい情報が入ってます。

このままだと不格好なので、整形します。

 

import pandas as pd

url = 'http://umano-ie.com/racesample/'
df = pd.read_html(url)

df[0].columns = ['枠', '馬番', '馬名', '性齢', '斤量', '騎手', '厩舎', '馬体重', 'オッズ', '人気'] #Columnを追加
df[0]= df[0].drop(df[0].index[[0]]) #dropメソッドでIndexの0番目を削除

print(df[0])

#実行結果
   枠 馬番         馬名  性齢    斤量    騎手      厩舎      馬体重    オッズ 人気
1  1  1   ラジャーバローズ  牡3  55.0    真中   角井(栗)  486(-8)   34.0  6
2  2  2     ワゲネリアン  牡3  55.0    福長   智道(栗)  450(-2)    9.5  4
3  3  3      レイドオロ  牡3  55.0  ロメーロ  富士澤(美)  480(-4)   13.7  5
4  4  4       ムカヒキ  牡3  55.0   河和田   智道(栗)  502(+4)    2.3  1
5  5  5      デラメンテ  牡3  55.0  D.ムロ   堀井(美)  484(-2)    5.4  3
6  6  6  ワンアンドオイリー  牡3  55.0    横乗   橋田(栗)  482(+4)  118.7  8
7  7  7        クサリ  牡3  55.0    竹豊   佐木(栗)  478(-2)   43.5  7
8  8  8  ディープゲリランテ  牡3  55.0   磐田康   小木(栗)  496(-6)    2.4  2

 

 

5.CSV出力する

Webページから出馬表を取り込むことができました。

このままでも良いのですが、ファイル出力してエクセルや別の形でデータを使いたくなるケースが出てくると思います。

そんな時は、DataFrame.to_csv() メソッドを使用して、取得したデータをCSV形式でファイル出力しましょう。

 

コードは以下のとおりです。

 

import pandas as pd

url = 'http://umano-ie.com/racesample/'
df = pd.read_html(url)

df[0].columns = ['枠', '馬番', '馬名', '性齢', '斤量', '騎手', '厩舎', '馬体重', 'オッズ', '人気'] #Columnを追加
df[0]= df[0].drop(df[0].index[[0]]) #dropメソッドでIndexの0番目を削除
df[0]= df[0].drop(df[0].columns[[5]], axis=1) #dropメソッドでColumnの5番目(=騎手)を削除

print(df[0])

df[0].to_csv('sample.csv', encoding='shift_jis') #実行しているパス直下にCSVファイルを生成

 

かっこの中身の説明ですが、左の”sample.csv”でファイル名を指定し、右の”encoding=’shift_jis’”が文字コードを指定しています。

エクセルで扱いたい場合、文字コードはシフトJISがよいでしょう。

エクセルで扱うことがなければ、UTF-8が無難です。

 

sample.csvが出力されているので、中身を確認してみましょう。

意図した内容になっていれば成功です。

 

 

6.まとめ

出馬表をまるっと取得して、CSV形式でファイル出力する方法をお伝えしました。

Pandasを使ったデータ取得とファイル出力はセットで覚えておくと、他にも応用できるので便利です。

他にもデータの整理や分析に便利な機能が備わっているので、次回以降でもっと掘り下げていきたいと思います。

 

「うまのいえ」では、今後もWebスクレイピングのネタを中心にブログを更新していきます。

また、足を運んでいただけると喜びます。

 

ご清聴ありがとうございました。