import requests from bs4 import BeautifulSoup # url = 'http://www.jfl.or.jp/jfl-pc/view/s.php?a=1436&f=2019A00101_spc.html' url = 'http://www.jfl.or.jp/jfl-pc/view/s.php?a=871&f=top_spc.html' 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) soup = BeautifulSoup(r.content, 'html5lib') for i in soup.select('table.score-table'): team = [ 'Honda FC' if 'Honda FC' in j.text else j.text for j in i.select('tr:nth-of-type(2) > th[class^="score-team"]') ] score = [j.text for j in i.select('tr:nth-of-type(2) > td.score-finish')] print(f'{team[0]: >11} {score[0]} - {score[1]} {team[1]}')
Ubuntu18.04にDokkuをインストール
# ホスト名設定 hostnamectl set-hostname dokku.192.168.0.100.xip.io # ホスト名登録 sudo nano /etc/hosts 192.168.0.100 dokku.192.168.0.100.xip.io dokku # GPGキーを登録 # E: This command can only be used by root # エラーがでるのでrootでインストール sudo su wget -nv -O - https://packagecloud.io/gpg.key | apt-key add - exit # リポジトリを登録 sudo nano /etc/apt/sources.list.d/dokku.list deb https://packagecloud.io/dokku/dokku/ubuntu/ bionic main # Docker Engineをインストール wget -nv -O - https://get.docker.com/ | sh # Dokku インストール sudo apt update && sudo apt upgrade sudo apt install dokku # インストール確認 id dokku ls -la /home/dokku/ # サービス確認 systemctl status dokku-installer.service # サービスが自動起動か確認 systemctl is-enabled dokku-installer.service # バージョン確認 dokku version # コア依存関係を設定 dokku plugin:install-dependencies --core --- # アップデート dokku-update # 再構築 dokku ps:rebuildall
JFL2018の強さを分析
!pip install pystan !pip install japanize-matplotlib
# 試合結果をスクレイピング import pandas as pd import japanize_matplotlib df_1st = pd.read_html('http://www.jfl.or.jp/jfl-pc/view/s.php?a=1270&f=2018A001_spc.html', skiprows=1, na_values='-') df_2nd = pd.read_html('http://www.jfl.or.jp/jfl-pc/view/s.php?a=1271&f=2018A003_spc.html', skiprows=1, na_values='-') dfs = df_1st + df_2nd dfs # 試合結果を結合 jfl_2018 = pd.concat(dfs, keys=[i for i in range(1, len(dfs)+1)], names=['節', '番号']) jfl_2018.columns=['日にち', '時間', 'ホーム', 'スコア', 'アウェイ', 'スタジアム', '備考'] jfl_2018.drop('備考', axis=1, inplace=True) jfl_2018.head() # スコアを分割 df_score = jfl_2018['スコア'].str.split('-', expand=True) df_score.columns = ['home', 'away'] df_score = df_score.astype(int) df_score.dtypes # 試合結果とスコアを結合 jfl_2018 = pd.concat([jfl_2018, df_score], axis=1) jfl_2018 # スコアをhome・awayに分離 df = df_score.stack().reset_index() df.drop(columns=['節','番号'], inplace=True) df.columns = ['team', 'score'] df['count'] = 1 df # スコアを集計 pv = df.pivot_table(values='count', columns='team', index='score', aggfunc = 'count', fill_value=0) pv.plot.bar(rot=0)
import pystan model_code = """ data { int N; // N Games int K; // K Teams int Th[N]; // Home Team ID int Ta[N]; // Away Team ID int Sh[N]; // Home Team score point int Sa[N]; // Away Team score point } parameters { real atk[K]; real def[K]; real home_power[K]; real<lower=0> sigma; real<lower=0> hp_sigma; } model { for (k in 1:K) { atk[k] ~ normal(0, sigma); def[k] ~ normal(0, sigma); home_power[k] ~ normal(0, hp_sigma); } for (n in 1:N) { Sh[n] ~ poisson(exp( (home_power[Th[n]] + atk[Th[n]]) - (def[Ta[n]]) )); Sa[n] ~ poisson(exp( (atk[Ta[n]]) - (def[Th[n]] + home_power[Th[n]]) )); } } generated quantities { real games[K, K, 2]; for (th in 1:K) { for (ta in 1:K) { games[th, ta, 1] = poisson_rng(exp((home_power[th] + atk[th]) - (def[ta]))); games[th, ta, 2] = poisson_rng(exp((atk[ta]) - (def[th] + home_power[th]))); } } } """ sm = pystan.StanModel(model_code=model_code) labels, team_name = pd.factorize(jfl_2018['ホーム']) jfl_2018['home_team_id'] = labels + 1 jfl_2018['away_team_id'] = team_name.get_indexer(jfl_2018['アウェイ']) + 1 N = len(jfl_2018) K = len(team_name) stan_input = {'N':N, 'K':K, 'Th':jfl_2018['home_team_id'], 'Ta':jfl_2018['away_team_id'], 'Sh' :jfl_2018['home'], 'Sa' :jfl_2018['away']} fit = sm.sampling(data=stan_input, seed=999) fit.plot() result = pd.DataFrame(fit.summary()['summary'], index=fit.summary()['summary_rownames'], columns=fit.summary()['summary_colnames']) result import numpy as np tk = {} params = fit.extract() atks = params['atk'] defs = params['def'] home_power = params['home_power'] games = params['games'] for k, team in enumerate(team_name): tk[team] = { "攻撃力": np.mean(atks[:, k]), "守備力": np.mean(defs[:, k]), "ホームアドバンテージ": np.mean(home_power[:, k]), } tdf = pd.DataFrame(tk).T tdf ax = tdf.plot.scatter(x='攻撃力', y='守備力', s=100, figsize=(10, 10)) for k, v in tdf.iterrows(): ax.annotate(k, xy=(v[2],v[1]), size=15)
eeepcにUbuntu Server 18.04をインストール
ファンがうるさくなったので分解したらいいと書いてあったのでキーボードを外してファンまで到達したのですがファンの外し方がわからないので断念
しかたがないのでファンが回らないCUIだと大丈夫だろということでUbuntu Server 18.04をインストールしました
http://www.ftp.ne.jp/Linux/packages/ubuntu/archive/
無線LAN設定
$ sudo apt install network-manager $ sudo nano /etc/netplan/99-manual.yaml
network: ethernets: enp1s0: dhcp4: true dhcp6: true link-local: [ ipv4, ipv6 ] wifis: wlp2s0: dhcp4: true dhcp6: true access-points: "xxxxxxxx": password: "yyyyyyyy" version: 2 renderer: NetworkManager
$ sudo netplan apply $ echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf $ sudo sysctl -p $ ip addr
$ sudo apt -y install language-pack-ja $ sudo update-locale LANG=ja_JP.UTF8 $ sudo apt install manpages-ja manpages-ja-dev $ man ls $ sudo dpkg-reconfigure tzdata
$ sudo systemctl -l status systemd-timesyncd $ sudo nano /etc/systemd/timesyncd.conf $ sudo systemctl restart systemd-timesyncd.service NTP=ntp.nict.jp
nano ~/.bashrc sudo nano /etc/skel/.bashrc
case "$TERM" in linux) LANG=C ;; *) LANG=ja_JP.UTF-8 ;; esac
pandasでJFLの戦績表を作成する
pip install lxml pip install html5lib
import pandas as pd dfs = pd.read_html( 'http://www.jfl.or.jp/jfl-pc/view/s.php?a=1411&f=2019A001_spc.html', skiprows=1, na_values='-') jfl_2019 = [ 'Honda FC', 'FC大阪', 'ソニー仙台FC', 'FC今治', '東京武蔵野シティFC', 'MIOびわこ滋賀', '奈良クラブ', 'ヴェルスパ大分', 'ラインメール青森', 'ヴィアティン三重', 'テゲバジャーロ宮崎', 'FCマルヤス岡崎', 'ホンダロックSC', '流経大ドラゴンズ龍ケ崎', '松江シティFC', '鈴鹿アンリミテッド' ] 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['戦'] = 'H' df_home.head() # アウェイの結果のみ df_away = df2.loc[:, ['アウェイ', 'ホーム', 'アウェイ得点', 'ホーム得点']] df_away.columns = ['チーム名', '対戦相手', '得点', '失点'] df_away['戦'] = 'A' df_away.head() # ホームとアウェイを結合 df_total = pd.concat([df_home, df_away]) df_total.head() # 勝敗を追加 def win_point(x): if x['得点'] > x['失点']: return '{}○{}'.format(x['得点'], x['失点']) elif x['得点'] < x['失点']: return '{}●{}'.format(x['得点'], x['失点']) else: return '{}△{}'.format(x['得点'], x['失点']) df_total['勝敗'] = df_total.apply(lambda x: win_point(x), axis=1) df_total # 戦績表作成 pv_score = df_total.pivot_table( values='勝敗', index=['チーム名', '戦'], columns='対戦相手', aggfunc=sum, fill_value='') # 指定順に並び替え new_idx = pd.MultiIndex.from_product( [jfl_2019, ['H', 'A']], names=pv_score.index.names) score = pv_score.reindex(new_idx, columns=jfl_2019) score.fillna('', inplace=True) score score.to_excel('2019_senseki.xlsx', sheet_name='戦績表')