LoginSignup
3
3

More than 3 years have passed since last update.

JFLの試合結果から順位表を作成

Last updated at Posted at 2020-10-06

はじめに

日本フットボールリーグオフィシャルWebサイトの日程・結果から試合結果をスクレイピング

スクレイピング

import requests
from bs4 import BeautifulSoup

url = "http://www.jfl.or.jp/jfl-pc/view/s.php?a=1542&f=2020A001_spc.html"

r = requests.get(url)
r.raise_for_status()

soup = BeautifulSoup(r.content, "html.parser")

data = []

for table in soup.find_all("table", class_="table-data"):

    trs = table.find_all("tr")

    th = int(trs[0].th.get_text(strip=True).strip("第節"))

    for i, tr in enumerate(trs[1:], 1):

        tds = [td.get_text(strip=True) for td in tr.find_all("td")]

        data.append([th, i] + tds)

データラングリング

import pandas as pd

df = pd.DataFrame(
    data, columns=["節", "番号", "日にち", "時間", "ホーム", "スコア", "アウェイ", "スタジアム", "備考"]
)

df.set_index(["節", "番号"], inplace=True)

df

df_score = (
    df["スコア"].str.split("-", expand=True).rename(columns={0: "ホーム得点", 1: "アウェイ得点"})
)

df_score["ホーム得点"] = pd.to_numeric(df_score["ホーム得点"], errors="coerce").astype("Int64")
df_score["アウェイ得点"] = pd.to_numeric(df_score["アウェイ得点"], errors="coerce").astype("Int64")

df1 = pd.concat([df, df_score], axis=1).dropna(subset=["ホーム得点", "アウェイ得点"])

# ホームの結果のみ
df_home = df1.loc[:, ["ホーム", "ホーム得点", "アウェイ得点"]].copy()
df_home.rename(columns={"ホーム": "チーム名", "ホーム得点": "得点", "アウェイ得点": "失点"}, inplace=True)
df_home["戦"] = "ホーム"
df_home.head()

# アウェイの結果のみ
df_away = df1.loc[:, ["アウェイ", "アウェイ得点", "ホーム得点"]].copy()
df_away.rename(columns={"アウェイ": "チーム名", "アウェイ得点": "得点", "ホーム得点": "失点"}, inplace=True)
df_away["戦"] = "アウェイ"
df_away.head()

# ホームとアウェイを結合
df_total = pd.concat([df_home, df_away])

# 得失点を計算
df_total["得失点"] = df_total["得点"] - df_total["失点"]


# 勝点追加
df_total["勝点"] = df_total["得失点"].apply(lambda x: 1 if x == 0 else 0 if x < 0 else 3)
df_total["勝敗"] = df_total["勝点"].replace({0: "敗戦", 1: "引分", 3: "勝利"})

df_total.head()

# 得点・失点・得失点・勝点 集計
pv_score = df_total.pivot_table(
    index="チーム名", values=["得点", "失点", "得失点", "勝点"], aggfunc=sum
)

pv_score

# 勝敗集計
pv_wl = pd.crosstab(df_total["チーム名"], [df_total["戦"], df_total["勝敗"]])
pv_wl

# 列名変更
# pv_wl.columns = ["勝利A", "引分A", "敗戦A", "勝利H", "引分H", "敗戦H"]

pv_wl.rename(columns={"アウェイ": "A", "ホーム": "H"}, inplace=True)
pv_wl.columns = pv_wl.columns.swaplevel(0, 1)
pv_wl.columns = ["".join(col).strip() for col in pv_wl.columns.values]

# 合計追加
pv_wl["勝利"] = pv_wl["勝利H"] + pv_wl["勝利A"]
pv_wl["引分"] = pv_wl["引分H"] + pv_wl["引分A"]
pv_wl["敗戦"] = pv_wl["敗戦H"] + pv_wl["敗戦A"]

# 試合数追加
pv_wl["試合数"] = pv_wl["勝利"] + pv_wl["引分"] + pv_wl["敗戦"]

# 確認
pv_wl

df2 = df_total.copy()

# 評価値を作成
df2["評価値"] = ((df2["勝点"]) * 10000) + (df2["得失点"] * 100) + df2["得点"]
df2

# 評価値集計
df3 = df2.pivot_table(
    values="評価値", index="チーム名", columns="節", aggfunc=sum, fill_value=0
)
df3

# 評価値の累計和
df_eval = df3.apply(lambda d: d.cumsum(), axis=1)
df_eval

# 評価値から順位作成
df_chart = df_eval.rank(ascending=False, method="min").astype(int)
df_chart.sort_values(by=df_chart.columns[-1], inplace=True)
df_chart

# 最終順位取得
s1 = df_chart.iloc[:, -1]
s1.name = "順位"

df_diff = df_chart.diff(axis=1).fillna(0).astype(int)
df_diff

#  前節差分
s2 = df_diff.iloc[:, -1].apply(lambda x: "-" if x == 0 else "▼" if x < 0 else "▲")
s2.name = "前節"
s2

# 全部を結合
df4 = pd.concat([pv_score, pv_wl], axis=1).join([s1, s2])

# 順位で昇順
df4.sort_values(["順位"], inplace=True)

df_rank = df4.reset_index().loc[
    :,
    [
        "前節",
        "順位",
        "チーム名",
        "勝点",
        "試合数",
        "勝利",
        "勝利H",
        "勝利A",
        "引分",
        "引分H",
        "引分A",
        "敗戦",
        "敗戦H",
        "敗戦A",
        "得失点",
        "得点",
        "失点",
    ],
]

df_rank

print(df_rank.to_markdown(index=False))

順位表

2020/10/07現在

前節 順位 チーム名 勝点 試合数 勝利 勝利H 勝利A 引分 引分H 引分A 敗戦 敗戦H 敗戦A 得失点 得点 失点
1 Honda FC 18 8 5 2 3 3 2 1 0 0 0 11 15 4
2 ヴェルスパ大分 15 7 5 2 3 0 0 0 2 2 0 5 14 9
3 テゲバジャーロ宮崎 14 7 4 1 3 2 1 1 1 1 0 6 11 5
4 MIOびわこ滋賀 13 8 4 2 2 1 1 0 3 1 2 4 17 13
5 いわきFC 13 8 4 3 1 1 0 1 3 1 2 0 14 14
6 ソニー仙台FC 13 8 4 1 3 1 1 0 3 1 2 0 13 13
7 松江シティFC 12 9 4 3 1 0 0 0 5 1 4 -5 10 15
8 FC大阪 11 8 3 2 1 2 2 0 3 1 2 3 12 9
9 奈良クラブ 11 8 3 1 2 2 1 1 3 2 1 2 10 8
10 鈴鹿ポイントゲッターズ 11 8 3 2 1 2 0 2 3 3 0 0 9 9
11 ホンダロックSC 10 8 3 0 3 1 0 1 4 4 0 -7 8 15
12 東京武蔵野シティFC 8 6 2 2 0 2 0 2 2 1 1 1 7 6
13 ヴィアティン三重 8 8 2 1 1 2 1 1 4 2 2 -3 8 11
14 ラインメール青森 8 7 2 1 1 2 1 1 3 1 2 -5 7 12
15 FCマルヤス岡崎 5 8 1 0 1 2 1 1 5 3 2 -5 7 12
16 高知ユナイテッドSC 3 8 0 0 0 3 2 1 5 2 3 -7 9 16

つづき

3
3
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
3
3