FC今治のゴール集計・先取点
!pip install lxml !apt install fonts-ipafont-gothic !rm /content/.cache/matplotlib/fontList.json """再起動""" import time import csv import requests from bs4 import BeautifulSoup # 試合数 n = 10 + 1 with open('fcimabari_goal.tsv', 'w') as fw: writer = csv.writer(fw, dialect='excel-tab', lineterminator='\n') # ヘッダー writer.writerow(['節', 'ホーム', 'アウェイ', '時間', 'チーム名', 'スコア', '背番号', '名前']) for i in range(1, n): url = 'http://www.fcimabari.com/team/game/result/JFL180{0:02d}.html'.format(i) headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko' } r = requests.get(url, headers=headers) if r.status_code == requests.codes.ok: soup = BeautifulSoup(r.content, 'lxml') home = soup.select_one('table.tableTypeResult > tr:nth-of-type(2) > td:nth-of-type(1)').get_text(strip=True) away = soup.select_one('table.tableTypeResult > tr:nth-of-type(2) > td:nth-of-type(3)').get_text(strip=True) tables = soup.select_one('table.tableType03') for trs in tables.select('tr'): temp = [] for tds in trs.select('td'): temp.append(tds.get_text(strip=True)) if len(temp) > 0: # 時間の分を削除 temp[0] = temp[0].strip('分') writer.writerow([i, home, away] + temp) # print(temp) time.sleep(3) import pandas as pd df = pd.read_table('fcimabari_goal.tsv', dtype = {'節' : 'int', 'ホーム' : 'object', 'アウェイ' : 'object', '時間' : 'int', 'チーム名' : 'object', 'スコア' : 'object', '背番号' : 'object', '名前' : 'object'}) df from google.colab import files df.to_csv('goal_list.csv') files.download('goal_list.csv') # 時間・チーム名を抽出 df1 = df.iloc[:, 3:5] # カウント用にカウントを追加しデーターを1 df1['カウント'] = 1 ''' # FC今治以外を欠測値に書き換え df1['チーム名'] = df1['チーム名'].where(df1['チーム名'] == 'FC今治') # 欠測値を敵チームに書き換え df1.fillna('敵チーム', inplace=True) df1 ''' # FC今治以外を敵チームに書き換え df1.loc[df1['チーム名'] != 'FC今治', 'チーム名'] = '敵チーム' df1.head() # 時間別ゴール集計 pv = df1.pivot_table(values = 'カウント', index = '時間', columns='チーム名', aggfunc = sum, fill_value = 0) pv.head() # 時間1~99の0のデーターフレームを作成 pv2 = pd.DataFrame(data=[[i, 0, 0] for i in range(1,100)], columns=['時間', '敵チーム', 'FC今治']) pv2.set_index('時間', inplace=True) pv2 # 0とゴール集計を結合 pv3 = pv2.append(pv) # 時間後にまとめる grouped = pv3.groupby(level=0) # 最後のデータのみ(ゴール集計) pv_goal = grouped.last() pv_goal #時間別ゴールグラフ import matplotlib.pyplot as plt plt.rcParams['font.family'] = 'IPAPGothic' pv_goal[::-1].plot.barh(figsize=(5, 20), xticks=[0, 1, 2, 3, 4]) # ゴールタイムランキング df.sort_values(by=['時間'], ascending=True).reset_index(drop=True).head(10) from google.colab import files pv_goal.to_csv('goal.csv') files.download('goal.csv') # 先取点 goal_time = df.loc[:, ['節','時間','チーム名']] goal_time # 先取点一覧 # goal_time.groupby('節')['時間'].min() first_goal = goal_time.groupby('節').apply(lambda x: x[x['時間'] == x['時間'].min()]) first_goal # FC今治の先取点の回数と試合数 print(first_goal['チーム名'].value_counts()['FC今治'], '/', df['節'].max()) # FC今治 df_time = df[df['チーム名']=='FC今治']['時間'] # 相手チーム # df_time = df[df['チーム名']!='FC今治']['時間'] df_time # 前半 df_time[df_time <= 48].count() # 後半 df_time[df_time > 48].count() # 全体 df_time.count() df_time.describe() df_count = df_time.value_counts().sort_index() df_count
PythonでスクレイピングしてテーブルをCSVに保存
Beautifulsoupの場合
import csv from bs4 import BeautifulSoup import requests url = 'http://www.example.com/' r = requests.get(url) if r.status_code == requests.codes.ok: soup = BeautifulSoup(r.content, 'html.parser') result = [[[td.get_text(strip=True) for td in trs.select('th, td')] for trs in table.select('tr')] for table in soup.select('table')] # 取得テーブル数確認 print(len(result)) # 取得テーブルデータ確認 print(result) with open('result.csv', 'w') as fw: writer = csv.writer(fw, dialect='excel', lineterminator='\n') # 0番目のテーブルを保存(リストの番号を変更する) writer.writerows(result[0])
Pandasの場合
import pandas as pd url = 'http://www.example.com/' dfs = pd.read_html(url, header=0, index_col=0) # 取得テーブル数確認 print(len(dfs)) # 取得テーブルデータ確認 print(dfs) # 結合 # df = pd.concat(dfs) # 0番目のテーブルを保存(リストの番号を変更する) dfs[0].to_csv('result.csv')
JFLの試合結果からランキングを作成
import pandas as pd url = 'http://www.jfl.or.jp/jfl-pc/view/s.php?a=1411&f=2019A001_spc.html' dfs = pd.read_html(url, skiprows=1, na_values='-') len(dfs) df = pd.concat( dfs, keys=[i for i in range(1, len(dfs) + 1)], names=['節', '番号']) df.columns = ['日にち', '時間', 'ホーム', 'スコア', 'アウェイ', 'スタジアム', '備考'] df.drop('備考', axis=1, inplace=True) df.head(10) # 欠損値確認 df[df.isnull().any(axis=1)] # スコアがないものを除去 df1 = df.dropna(subset=['スコア']) # スコアを分割、スコアを削除、結合 df2 = pd.concat( [df1, df1['スコア'].str.split('-', expand=True)], axis=1).drop( 'スコア', axis=1) # 名前をホーム得点、アウェイ得点に変更 df2.rename(columns={0: 'ホーム得点', 1: 'アウェイ得点'}, inplace=True) # ホーム得点、アウェイ得点を文字から整数に変更 df2['ホーム得点'] = df2['ホーム得点'].astype(int) df2['アウェイ得点'] = df2['アウェイ得点'].astype(int) df2.dtypes # ホームの結果のみ df_home = df2.loc[:, ['ホーム', 'ホーム得点', 'アウェイ得点']].reindex() df_home.columns = ['チーム名', '得点', '失点'] df_home['戦'] = 'ホーム' df_home.head() # アウェイの結果のみ df_away = df2.loc[:, ['アウェイ', 'アウェイ得点', 'ホーム得点']] df_away.columns = ['チーム名', '得点', '失点'] df_away['戦'] = 'アウェイ' df_away.head() # ホームとアウェイを結合 df_total = pd.concat([df_home, df_away]) # 得失点を計算 df_total['得失点'] = df_total['得点'] - df_total['失点'] df_total.head() # 勝敗を追加 def win_or_loss(x): if x['得点'] > x['失点']: return '勝利' elif x['得点'] < x['失点']: return '敗戦' else: return '引分' df_total['勝敗'] = df_total.apply(lambda x: win_or_loss(x), axis=1) df_total.head() # 勝点を追加 def win_point(x): if x['得点'] > x['失点']: return 3 elif x['得点'] < x['失点']: return 0 else: return 1 df_total['勝点'] = df_total.apply(lambda x: win_point(x), axis=1) df_total.head() # 得点・失点・得失点・勝点 集計 pv_score = df_total.pivot_table( values=['得点', '失点', '得失点', '勝点'], index='チーム名', aggfunc=sum) pv_score.head() # 集計用にカウント追加 df_total['カウント'] = 1 # 得点・失点・得失点・勝点 集計 pv_wl = df_total.pivot_table( values='カウント', index='チーム名', columns=['戦', '勝敗'], aggfunc=sum, fill_value=0) pv_wl # 列名変更 pv_wl.columns = ['勝利A', '引分A', '敗戦A', '勝利H', '引分H', '敗戦H'] # 合計追加 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 df3 = df_total.pivot_table( values='勝点', index='チーム名', columns='節', aggfunc=sum, fill_value=0) df3 df_wp = df3.apply(lambda d: d.cumsum(), axis=1) df_wp df4 = df_total.copy() # 評価値を作成 df4['評価値'] = (df4['勝点'] * 10000) + (df4['得失点'] * 100) + df4['得点'] df4 # 評価値集計 df5 = df4.pivot_table( values='評価値', index='チーム名', columns='節', aggfunc=sum, fill_value=0) df5 # 累計評価値 df_eval = df5.apply(lambda d: d.cumsum(), axis=1) df_eval # 累計評価値をランキングに変換 df_chart = df_eval.rank(ascending=False, method='min').astype(int) df_chart # 前ランキングとの差分 df6 = df_chart.copy() df_diff = df6.diff(axis=1).fillna(0) def arrow_up(x): if x > 0: return '▼' elif x < 0: return '▲' else: return '-' s1 = df_diff.iloc[:, -1].apply(lambda x: arrow_up(x)) s1.name = '前節' df7 = pd.concat([pv_score, pv_wl], axis=1).join(s1) # 評価値を作成 df7['評価値'] = (df7['勝点'] * 10000) + (df7['得失点'] * 100) + df7['得点'] # ランキング df7['順位'] = df7['評価値'].rank(ascending=False, method='min').astype(int) # 順位で昇順 df7.sort_values(['順位'], inplace=True) df7 # チーム名をインデックスから解除 df8 = df7.reset_index() df_rank = df8.loc[:, [ '前節', '順位', 'チーム名', '勝点', '試合数', '勝利', '勝利H', '勝利A', '引分', '引分H', '引分A', '敗戦', '敗戦H', '敗戦A', '得失点', '得点', '失点' ]] df_rank df_rank.to_excel('2019_ranking.xlsx', sheet_name='ランキング', index=False)
Ubuntu Python3環境設定
Python in Visual Studio Code – April 2018 Release - Python
sudo apt install git sudo apt install python3-pip python3-dev python3-tk python3-venv python3-bs4 python3-requests python3-html5lib python3-lxml jupyter python3-numpy python3-pandas python3-matplotlib python3-seaborn python3-openpyxl black mkdir workspace cd workspace python3 -m venv scraping source scraping/bin/activate pip3 install requests pip3 install beautifulsoup4 pip3 install lxml pip3 install html5lib pip3 install black pip3 install pylint
pip3 install pipenv --user source ~/.profile pipenv --three pipenv lock --pre pipenv install beautifulsoup4 pipenv install requests pipenv install html5lib pipenv install lxml pipenv install --dev pylint pipenv install --dev black pipenv install tensorflow pipenv install keras pipenv install jupyter pipenv install matplotlib pipenv install seaborn pipenv install pandas pipenv install openpyxl pipenv install selenium pipenv install --dev flake8 pipenv install --dev pycodestyle pipenv install --dev pydocstyle pipenv install --dev autopep8 pipenv install --dev yapf
Pipfile
[[source]] url = "https://pypi.org/simple" verify_ssl = true name = "pypi" [packages] "beautifulsoup4" = "*" requests = "*" "html5lib" = "*" lxml = "*" selenium = "*" tensorflow = "*" keras = "*" jupyter = "*" matplotlib = "*" seaborn = "*" pandas = "*" openpyxl = "*" [dev-packages] pylint = "*" "flake8" = "*" pycodestyle = "*" pydocstyle = "*" "autopep8" = "*" yapf = "*" [requires] python_version = "3.6" [scripts] fix = "yapf -i -r ."
Windows10 Spring Creators UpdateにPrimoRamdiskをブルースクリーン
とりあえずインストールなしで動かしている