乙Py先生のプログラミング教室
初学者のためのプログラミング学習サイト

Python

プログラミング未経験の方のための
プログラミング学習講座を作成しました

その名も
「1時間で学べるPythonプログラミング」


講義動画はこちら




この講座は初学者の方が
短時間でPython言語を学ぶことのできる
プログラミング学習用の講座です

プログラミングが分からないない方は
Python言語を通じて
プログラミングの基礎を学習できます

講座は動画に加えてGoogle Colabを用いて
手元でコードを動かすことのできます
コードがどう動くのかを確認をしながら
進めていってください

資料はここ:
Google Colabの資料


00:00 1.はじめに
02:13 2.導入方法
02:55 3.GoogleColaboratoryの操作方法
06:19 4.Pythonの計算の基礎
27:27 5.Pythonの制御文
42:14 6.Pythonのクラス
49:11 7.Pythonのその他構文
64:30 8.まとめ

なおPythonチートシートを作成しています。

コーディングに迷った際に役に立ち

WEB検索する時間を無くして

作業時間を効率化できます。

note
Pythonチートシート


 

今回は現在の成績から
大谷選手の2024シーズン結果を
予測してみました。

解説動画はこちら




はじめに

メジャーリーグ2024年シーズン
大谷選手の現在までの成績(05/25まで)
こちらを使って今シーズンの成績を予測します。



今シーズンの全打席結果が
掲載されているサイトが有ったため
そちらからデータを取得します。

掲載先

こちらによると現時点では
203打数69安打 打率.340
13本塁打 35打点 39得点 13盗塁
という成績でした。


現時点の成績

こちらの結果から分析すると
本塁打:0.05652173913043478
三塁打:0.008695652173913044 
二塁打:0.0782608695652174 
 安打:0.1565217391304348
 三振:0.1826086956521739
 四球:0.10869565217391304
アウト:0.40869565217391307
という確率になりました。

この確率を用いて
シミュレーションを行います。

メジャーリーグの年間平均打席数が650打席
これを1000シーズン行ったという設定です。

import random
import pandas as pd

# バッティング結果の確率を設定
batting_results = {
    "homerun": 0.05652173913043478, # 本塁打
    "triple": 0.008695652173913044, # 三塁打
    "double": 0.0782608695652174,  # 二塁打
    "single": 0.1565217391304348,  # 安打
    "strike": 0.1826086956521739, # 三振
    "walk": 0.10869565217391304, # 四球
    "out":  0.40869565217391307 # その他のアウト
}

def simulate_batting():
    rand = random.random()
    cumulative_probability = 0.0
    for result, probability in batting_results.items():
        cumulative_probability += probability
        if rand < cumulative_probability:
            return result
    return "out"

base = []
for i in range(1000):
    tmp = {k:0 for k in batting_results.keys()}
    n = 650
    for i in range(n):
        s = simulate_batting()
        if s in tmp:
            tmp[s]+=1
        else:
            tmp[s]=1
    base.append(tmp)

df = pd.DataFrame(base)
df["hits"] = df["homerun"] + df["triple"] + df["double"] + df["single"]
df.describe()

ここからホームランと
ヒット数を予測します。
mport pandas as pd
import matplotlib.pyplot as plt
import numpy as np

# homerunの平均値と標準偏差を計算
mean = df['homerun'].mean()
std = df['homerun'].std()
print(f"{int(mean-std)}, {int(mean)}, {int(mean+std)}")

# ヒストグラムを表示
df['homerun'].hist(bins=20, alpha=0.7)

# 平均値、標準偏差±1のラインを描画
plt.axvline(x=mean, color='red', linestyle='--', label='mean')
plt.axvline(x=mean+std, color='green', linestyle='--', label='std+1')
plt.axvline(x=mean-std, color='blue', linestyle='--', label='std-1')

# 凡例を表示
plt.legend()
plt.show()
download-1

# hitsの平均値と標準偏差を計算
mean = df['hits'].mean()
std = df['hits'].std()
print(f"{int(mean-std)}, {int(mean)}, {int(mean+std)}")

# ヒストグラムを表示
df['hits'].hist(bins=20, alpha=0.7)

# 平均値、標準偏差±1のラインを描画
plt.axvline(x=mean, color='red', linestyle='--', label='mean')
plt.axvline(x=mean+std, color='green', linestyle='--', label='std+1')
plt.axvline(x=mean-std, color='blue', linestyle='--', label='std-1')

# 凡例を表示
plt.legend()
plt.show()
download


まとめ
05/25日までのペースだと
ホームラン数 : 36本(±6)
ヒット数 : 195本(±12)
あたりに落ち着く可能性が高いです。

年間40本塁打
200安打は少し、厳しいかもしれませんが
これからの活躍に期待したいですね


きょうはここまでです
それでは。

今回は桁の大きな数字を計算する
方法についての解説です。

解説動画はこちら




2の1億乗と10の3000万乗

さて、早速ですが
どちらが大きい数字でしょうか

プログラミングであれば
ある程度の大きな数字でも
簡単に計算できます。

ただし、大きすぎる数字になると
計算が困難になってきます。

print(2 ** 100000000)
# ValueError: Exceeds the limit (4300) for integer string conversion; use sys.set_int_max_str_digits() to increase the limit

これを解くには
少し工夫をしないといけません。


対数関数(LOG)

ここで少しだけ対数の説明です。
スクリーンショット 2024-05-18 15.26.15
a を何乗したら
b になるかというのが
Xです。


5 を 3 回かけたら 125 になるので
log5 125 = 3
になりますね。

また対数の性質として
スクリーンショット 2024-05-18 15.26.24
という形に変形が行えます。

P乗の対数は、対数のP倍に等しい

これを用いれば
どちらの数字が大きくなるかは
計算ができるはずです。

Pythonでは対数を扱うものとして
mathライブラリというものがあります。

これで対数の計算を行う事ができます。

Log2 と Log10 を使って
式を変形させます。
p * log2
p * log10

import math

print(math.log(2) * 100000000)
print(math.log(10) * 30000000)
69314718.05599453
69077552.78982137

これを見ると
2の1億乗の方が大きくなりますね




2の10000乗って何桁になる?

これもプログラミングでは簡単に解ける問題ですが
頭の中だけで考えるのは少し大変ですね

これも対数関数を用いてうまく求める事ができます。

常用対数(10を底とする対数)というものがあり
桁数は `2の常用対数 * 乗数 + 1` で求めることができます。
(小数点以下は切り捨て)
import math
l2 = math.log10(2) p = 10000 print(int(l2 * p) + 1)
3011

2の10000乗 は
3011桁になります。


このようにして
かなり桁の大きな数字の計算は
時間が掛かったり、計算自体ができない場合があります。

そんな時はlogを用いて
うまく数式を変換させてあげると
数字の比較などが行いやすくなります。

競技プログラミングなどでも
よく出る計算手法なので
覚えておくと良いかもしれませんね


今回はLOG(対数)に関する解説でした
それでは。

今回は子供の日という事で
ステレオグラムで遊んでみました。

解説動画はこちら



ステレオグラムとは(立体画)


立体図は、立体的印象をもつように描かれた
平面に描かれた図や絵あるいは写真のことで

目の焦点を意図的に前後にずらして合わせることで
左右の絵を別々の目で見ることにより
立体的に見ることができる画像です。


今回はドットのパターンを用意して
そこに浮かび上がらせる画像を組み合わせて作っています。

見方は、黒いドットが3つになるように
重ね合わせて目の焦点を合わしていくと
見る事ができると思います。



ステレオグラムを作成するコード

import numpy as np
import matplotlib.pyplot as plt
import cv2
import warnings
warnings.simplefilter("ignore")
%matplotlib inline

def make_dots(shape=(16, 16), levels=64):
    return np.random.randint(0, levels - 1, shape) / levels

def make_text_img(text='A', shape=(400, 600)):
    font = cv2.FONT_HERSHEY_SIMPLEX
    (text_width, text_height), _ = cv2.getTextSize(text, font, 5, 30)
    img = np.zeros((text_height + 50, text_width + 200), dtype=np.float)
    cv2.putText(img, text, (100, text_height+10), font, 5, (255, 255, 255), 30, cv2.LINE_AA)
    img_resized = cv2.resize(img, shape[::-1], interpolation=cv2.INTER_AREA)
    return img_resized

def normalize(depthmap):
    if depthmap.max() > depthmap.min():
        return (depthmap - depthmap.min()) / (depthmap.max() - depthmap.min())
    else:
        return depthmap

def make_autostereogram(text, shift_amplitude=0.1, invert=False):
    depthmap = make_text_img(text=text)
    pattern = make_dots(shape=(64, 64))
    depthmap = normalize(depthmap)
    if invert:
        depthmap = 1 - depthmap
    autostereogram = np.zeros_like(depthmap, dtype=pattern.dtype)
    for r in np.arange(autostereogram.shape[0]):
        for c in np.arange(autostereogram.shape[1]):
            if c < pattern.shape[1]:
                autostereogram[r, c] = pattern[r % pattern.shape[0], c]
            else:
                shift = int(depthmap[r, c] * shift_amplitude * pattern.shape[1])
                autostereogram[r, c] = autostereogram[r, c - pattern.shape[1] + shift]
    autostereogram[48:53, 248:253] = 0
    autostereogram[48:53, 348:353] = 0
    return autostereogram

実行する際は浮かび上がらせる画像を
テキストとして文字列を変更します。
autostereogram = make_autostereogram(text='A')
plt.figure(figsize=(8,8))
plt.imshow(autostereogram, cmap='gray')
plt.axis("off")
plt.show()
download

この画像の上にある黒い点が
4つになるようにぼんやり見た後に
点が3つになるように焦点をずらします。

そうすると A という文字が
浮かび上がって見えると思います。


問題

さっきの練習を少し難しくした3文字です。
g1





新宿の掲示板に書いてある3文字です。
g2




自分の大好きな5文字です。
g3





見えましたか?


見えない方は
努力が足りていないです!!!!!!!!

見えた方は
今日の1日がとても
すこやかに過ごせるでしょう!!!

色々画像を作って遊んでみて下さい。

それでは。

今回はMLB2023の大谷投手の
全投球データを見てみることとしました。

解説動画はこちら




データの入手先

今回取り扱っているデータは
Baseball Savantというサイトから入手できます。

Baseball Savant


画面の「Pitchers」に名前を入力して「Search」
結果画面の右側にある
「Download Data as Comma Separated Values File」を
クリックするとCSVがダウンロードできます。




データの読み込み

Google Colabでデータを見る際は
事前にダウンロードしたデータを
ファイル置き場にアップロードしておいて下さい。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv('savant_data.csv')
print(df.shape)
df.head()




ピッチャー大谷選手のスタッツ


全球種
name_data=[
  ['Sweeper','スィーパー','スライダーよりも横曲がりの大きいボール'],
  ['4-Seam Fastball','直球','直線的な豪速球(縫い目:シームが4回見える)'],
  ['Cutter','カット・ファスト・ボール','直球とほぼ同じ球速で小さく鋭く変化するボール'],
  ['Split-Finger','フォーク','打者の近くで落下する変化球'],
  ['Sinker','シンカー','投手の利き腕方向に曲がりながら落ちる球種'],
  ['Curveball','カーブ','比較的遅い球速で大きく曲がる球'],
  ['Slider','スライダー','ブレーキがかかった大きく曲がる球'],
  ]
name_df = pd.DataFrame(name_data,columns=["pitch_name","球種名","説明"])
pitch_df = pd.DataFrame(df.pitch_name.value_counts()).reset_index()
pd.merge(pitch_df,name_df,on='pitch_name', how='left')


投球結果
stats_df = pd.DataFrame(df.description.value_counts()).reset_index()
stats_df


ストライクの投球
plt.figure(figsize=(10, 6))
x = df['plate_x']
z = df['plate_z']
d = df['description']
cs = ['blue' if 'strike' in c else 'grey' for c in d]
plt.scatter(x, z, c=cs)
plt.xlim(-10,10)
plt.ylim(-2, 6)
plt.show()
download-2





球種による変化量
plt.figure(figsize=(10, 6))
pitchtypes = ['Sweeper', '4-Seam Fastball', 'Cutter', 
'Split-Finger', 'Sinker', 'Curveball', 'Slider'] colors = ['red', 'brown', 'orange', 'aqua', 'olive', 'magenta', 'lime'] s = set() for index, row in df.iterrows(): x = row['pfx_x'] * (-30.48) # センチ換算(逆方向) z = row['pfx_z'] * ( 30.48) # センチ換算 n = pitchtypes.index(row['pitch_name']) if n not in s: s.add(n) plt.scatter(x, z, color=colors[n], label=row['pitch_name']) else: plt.scatter(x, z, color=colors[n]) plt.legend(loc="upper left", fontsize=12) plt.xlim(-100,100) plt.ylim(-60, 60) plt.show()
download





この様な感じで
投球データを色々な角度から
分析する事ができるデータになっています。

今回紹介した以外にも
たくさんのデータが存在するので
色々遊ぶ事ができると思います。

あそびたい方は
是非データをダウンロードして
こねくりまわしてみて下さい。

それでは。

このページのトップヘ