1
1

競馬レース結果の取得して色々見てみたい 前処理編

Last updated at Posted at 2024-03-14

初めに

最近競馬にハマっており、データを見ながら予想や結果を語りたいなと思うようになりました。
なので、結果を可視化してみて色々見てみたいと思います。

当方開発経験がなく、今までほぼpythonを触ったこともない人間ですので拙いコードを書きますが、暖かい目で見て頂ければと思います。

データの取得

netkeibaから、2010年~2013年のレース結果を用いたいと思います。
netkeiba

また、今回はデータの可視化が目的なので、データを取得する部分に関しては下記サイト様を参考にさせていただきました。
リラックスした生活を過ごすために

取得したデータ

import pandas as pd
df=pd.read_csv('レース結果.csv', encoding='cp932')
df.head()

image.png

データの加工

欠損値の確認、除去
df.isnull().sum()

image.png

df=df.dropna()
df.isnull().sum()

image.png

データの全角、半角を除去

データ内に「ダート 」のように文字の後に半角があったので、除去します。

df=df.map(lambda x : x.strip() if isinstance(x, str) else x)
データ型の確認
df.dtypes

image.png

タイムを秒に変換

機械学習を行うとなった場合、説明変数にしたいので、あらかじめ行っておきます。

def object_to_seconds(object):
    minutes,seconds=map(float,object.split(':'))
    total_seconds=minutes*60+seconds
    return total_seconds
df.insert(loc=df.columns.get_loc('タイム') + 1, column='タイム_秒', value=df['タイム'].apply(object_to_seconds))

df.head()

image.png

開催日変換

開催日が20221023のようになっているデータは文字化けをしており、上手く取得できなかったので、手作業で保存し、その後型変換を行いました。

df['開催日']=pd.to_datetime(df['開催日'], format='%Y年%m月%d日')
df.head()

image.png

通過表記変換

m月d日のような表示であったり、
「1-1-1」の表記が、2001/1/1のような表示になっているので修正します

import re
# 通過のフォーマットを変換する関数
def convert_pass(pass_str):
    pattern_1 =r'(\d{1,2})月(\d{1,2})日'
    pattern_2 =r'(\d{1,4})/(\d{1,2})/(\d{1,2})'
    # 'm月d日の場合はm-dの形にして返す
    if re.match(pattern_1, pass_str):
        return re.sub(pattern_1,r'\1-\2',pass_str)
    # 「1-1-1」の表記が、2001/1/1のような表示になっているので修正する
    elif re.match(pattern_2, pass_str):
        match=re.match(pattern_2, pass_str)
        t1=match.group(1)
        t2=match.group(2)
        t3=match.group(3)
        if t1[-2]=='0':
            t1=t1[-1]
        else:
            t1=t1[-2]
        return f'{t1}-{t2}-{t3}'
    # 上記以外の場合は元の文字列を返す
    else:
        return pass_str
# 通過カラムを変換
df['通過'] = df['通過'].apply(convert_pass)
競馬場追加

競馬場カラムの追加を行います


df['競馬場']=df['開催場所'].map(lambda x:re.sub(r'\d+回\s*|\s*\d+日目', '', x))
df.head()

image.png

着順変換

着順カラムに失格や14(降)の表記があります。
失格は除外し、降着は(降)を取り除き、着順をint型に変換します。

# 失格は除外、降着は(降)を取り除く処理
df = df[df['着順'] != '']

def convert_rank(rank_str):
    pattern = r'(\d{1,2})(降)?' 
    match = re.match(pattern, rank_str)
    if match:
        return match.group(1)  
    else:
        return rank_str
df['着順'] = df['着順'].apply(convert_rank)

print(df['着順'].unique())
#着順をint型に修正
df['着順'] = df['着順'].astype(int)

ファイル出力

保存用に加工後ファイルを出力しておきます。

#加工後データcsv出力

df.to_csv('レース結果加工後.csv',index=False,encoding='cp932')
print('出力完了しました')

取得したデータを競馬場毎に分割して出力します。

レース種別(芝、ダート)に分けた後、各競馬場に分割します。。

#馬場,競馬場ごとにcsv出力

groundtype_list=['ダート','']
place_list=['札幌', '函館', '福島','新潟','東京','中山','中京','京都','阪神','小倉']

for ground in groundtype_list:
    df_ground = df[df['馬場'] == ground]
    
    for place in place_list:
        df_place = df_ground[df_ground['競馬場'] == place]
        
        # df_placeが空でない場合のみ処理を実行
        if not df_place.empty:
            title = 'レース結果_{}/レース結果_{}_{}.csv'.format(ground,ground,place)
            df_place.to_csv(title, index=False, encoding='cp932')
            print("処理完了しました:", title)
        else:
            print("データがありません:", title)

あとがき

本当に初めてなので、未熟な部分や問題があるかと思います。
とりあえず分割したデータでグラフを出力できたので、前処理としてはこのあたりで止めておきます。
今後データをいじった際に必要になったとき追記します。

前処理が9割なんて話をよく聞いていましたが、本当にその通りで、ここまでするのにとんでもなく時間がかかりました。

今回作成したコードは以下のmaesyori.ipynbにのせてあります(少しごちゃついてて見にくいですが、、)ので、興味あればのぞいてみてください。

次回は本当に簡単な可視化作業から行っていきたいと思います。
以上ここまで読んで頂きありがとうございました。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1