u++の備忘録

Jリーグ2018年シーズンの勝ち点推移を可視化 pythonでデータ取得から可視化まで

2018年シーズンのJ1リーグでは、序盤にサンフレッチェ広島が独走していましたが、7月のW杯中断明けごろから失速。後半になって追い上げた昨年王者の川崎フロンターレに首位を譲る展開になっています。

川崎フロンターレの驚異的な追い上げがどの程度か気になってので、シーズン途中ではありますが勝ち点推移を可視化してみました。第29節までのデータを可視化に利用しています。

f:id:upura:20181020193126p:plain

処理の流れ

  1. BeautifulSoupでスクレイピング
  2. pandasで加工
  3. matplotlibで可視化

一連の流れは非常に雑なコードですが下記で確認できます。

github.com

BeautifulSoupでスクレイピング

Yahoo!のサイトからデータを取得して、節ごとにcsvで保存しました。

soccer.yahoo.co.jp

def save_result_data(setsu):
    url = 'https://soccer.yahoo.co.jp/jleague/schedule/j1/' + str(setsu) + '/all'
    html = urlopen(url)
    bsObj = BeautifulSoup(html, "html.parser")
    table = bsObj.findAll("table")[0]

    rows = table.findAll("tr")

    csvFile = open("result" + str(setsu) + ".csv", 'wt', newline = '', encoding = 'utf-8')
    writer = csv.writer(csvFile)

    try:
        for row in rows:
            csvRow = []
            for cell in row.findAll(['td', 'th']):
                csvRow.append(cell.get_text())
            writer.writerow(csvRow)
    finally:
        csvFile.close()

for setsu in range(1, 35):
    save_result_data(setsu)

pandasで加工

今回の目的に沿うようにデータを加工しました。

加工前(データの一部)

f:id:upura:20181020193134p:plain

加工後(データの一部)

f:id:upura:20181020193139p:plain

加工前は行ごとに試合の情報を保持している形式でしたが、加工後は行ごとに1チームの試合ごとに「日付」「獲得勝ち点」の情報を紐づけました。

matplotlibで可視化

あとはチームごとに勝ち点推移を可視化します。

team0 = res[res['teams'] == '川崎F']
team0 = team0.sort_values('dates')
team0['accum_scores'] = team0['scores'].cumsum()
plt.plot(team0['dates'], team0['accum_scores'], label='Kawasaki')

上のコードの1行ごとに、それぞれ下記の操作をしています。

  1. 川崎フロンターレ」のデータに絞り込む
  2. 開催日でデータをソート
  3. 各試合終了時点での累積和(勝ち点)を計算
  4. 折れ線グラフで可視化

所感

勝ち点推移の可視化に適したデータ構造の持ち方が分からず、思ったよりも苦戦しました。