Featured image of post 【pybaseball基礎編③】試合単位のデータ取得

【pybaseball基礎編③】試合単位のデータ取得

pybaseballを使ってMLBの試合単位のStatcastデータを取得する方法を解説します。

記事のシリーズ

  1. pybaseball基礎編① pybaseballのライブラリの概要とインストール
  2. pybaseball基礎編② シーズン単位のデータ取得
  3. pybaseball基礎編③ 試合単位のデータ取得【本記事】
  4. pybaseball基礎編④ 打席単位のデータ取得(予定)
  5. pybaseball基礎編⑤ 1球単位のデータ取得(予定)
  6. pybaseball基礎編⑥ 打球単位のデータ取得(予定)
  7. pybaseball基礎編⑦ 投球単位のデータ取得(予定)

はじめに

前回の「pybaseball基礎編②」では、シーズン単位でMLBのStatcastデータを取得する方法を紹介しました。

今回は一段階細かくして、1試合単位でデータを取得し、pandasを使って試合内容を集計する方法を解説します。

この記事では、次の流れを実践します。

  • 特定日のStatcastデータを取得する
  • チームを指定して対象試合を絞り込む
  • game_pkを確認する
  • statcast_single_game()で1試合のデータを取得する
  • 1試合の投球数や球種を集計する
  • 打球速度や打球角度を調べる
  • 大谷翔平選手の打席・打球を確認する

1. 試合単位のデータとは?

Statcastの元データは、基本的に1球につき1行という投球単位のデータです。

イメージとしては、

シーズン
  ↓
試合
  ↓
打席
  ↓
投球
  ↓
打球

という階層になっています。

そのため、statcast_single_game()で1試合を指定しても、返ってくるDataFrameが「1試合=1行」になるわけではありません。

1試合分の投球データを取得し、それをpandasで集計することで、

  • 総投球数
  • イニング別投球数
  • 球種別投球数
  • 平均球速
  • 打球数
  • 最大打球速度

などの「試合単位」の指標を作ります。

2. pybaseballとStatcastの関係

データの流れを整理すると、

MLB
 ↓
Statcast
 ↓
Baseball Savant
 ↓
pybaseball
 ↓
pandas DataFrame
 ↓
Pythonで分析

というイメージです。

StatcastはMLBのトラッキングシステムによって取得されるデータです。

Baseball Savantでは、MLBのStatcast関連データを検索・閲覧できます。

pybaseballを使うと、これらのデータをPythonから取得して、pandasのDataFrameとして扱えます。

つまり、pybaseballそのものが野球データベースというわけではなく、野球データをPythonから扱いやすくするためのアクセス手段と考えると分かりやすいです。

3. 特定日のStatcastデータを取得する

まず、2025年6月16日のデータを取得します。

from pybaseball import statcast

data = statcast("2025-06-16", "2025-06-16")

display(data.head())

print("行数:", len(data))
print("列数:", len(data.columns))

出力結果

index pitch_type game_date release_speed release_pos_x release_pos_z player_name batter pitcher events description spin_dir spin_rate_deprecated break_angle_deprecated break_length_deprecated zone des game_type stand p_throws home_team
1453 FF 2025-06-16 00:00:00 93.5 -2.44 5.35 Yates, Kirby 642180 489446 field_out hit_into_play <NA> <NA> <NA> <NA> 2 Tyler Wade pops out to third baseman Max Muncy. R L R LAD
1463 FS 2025-06-16 00:00:00 86.7 -2.47 5.17 Yates, Kirby 642180 489446 NaN called_strike <NA> <NA> <NA> <NA> 13 NaN R L R LAD
1541 FF 2025-06-16 00:00:00 93.0 -2.46 5.21 Yates, Kirby 642180 489446 NaN foul <NA> <NA> <NA> <NA> 3 NaN R L R LAD
1561 FS 2025-06-16 00:00:00 85.9 -2.39 5.18 Yates, Kirby 578428 489446 field_out hit_into_play <NA> <NA> <NA> <NA> 9 Jose Iglesias lines out to shortstop Mookie Betts. R R R LAD
1635 FF 2025-06-16 00:00:00 93.4 -2.35 5.38 Yates, Kirby 578428 489446 NaN foul <NA> <NA> <NA> <NA> 11 NaN R R R LAD
行数: 1960
列数: 119

取得したデータは、基本的に1球単位です。

例えば、次のように主要な列を確認できます。

display(
    data[
        [
            "game_date",
            "game_pk",
            "inning",
            "pitcher",
            "batter",
            "pitch_name",
            "release_speed"
        ]
    ].head()
)

出力結果

index game_date game_pk inning pitcher batter pitch_name release_speed
1453 2025-06-16 00:00:00 777490 9 489446 642180 4-Seam Fastball 93.5
1463 2025-06-16 00:00:00 777490 9 489446 642180 Split-Finger 86.7
1541 2025-06-16 00:00:00 777490 9 489446 642180 4-Seam Fastball 93.0
1561 2025-06-16 00:00:00 777490 9 489446 578428 Split-Finger 85.9
1635 2025-06-16 00:00:00 777490 9 489446 578428 4-Seam Fastball 93.4

4. チームを指定して対象試合を絞り込む

特定チームだけを分析したい場合は、teamを指定できます。

from pybaseball import statcast

dodgers_data = statcast(
    "2025-06-16",
    "2025-06-16",
    team="LAD"
)

display(dodgers_data.head())

print("行数:", len(dodgers_data))

出力結果

index pitch_type game_date release_speed release_pos_x release_pos_z player_name batter pitcher events description spin_dir spin_rate_deprecated break_angle_deprecated break_length_deprecated zone des game_type stand p_throws home_team
82 FF 2025-06-16 00:00:00 93.5 -2.44 5.35 Yates, Kirby 642180 489446 field_out hit_into_play <NA> <NA> <NA> <NA> 2 Tyler Wade pops out to third baseman Max Muncy. R L R LAD
87 FS 2025-06-16 00:00:00 86.7 -2.47 5.17 Yates, Kirby 642180 489446 NaN called_strike <NA> <NA> <NA> <NA> 13 NaN R L R LAD
97 FF 2025-06-16 00:00:00 93.0 -2.46 5.21 Yates, Kirby 642180 489446 NaN foul <NA> <NA> <NA> <NA> 3 NaN R L R LAD
98 FS 2025-06-16 00:00:00 85.9 -2.39 5.18 Yates, Kirby 578428 489446 field_out hit_into_play <NA> <NA> <NA> <NA> 9 Jose Iglesias lines out to shortstop Mookie Betts. R R R LAD
109 FF 2025-06-16 00:00:00 93.4 -2.35 5.38 Yates, Kirby 578428 489446 NaN foul <NA> <NA> <NA> <NA> 11 NaN R R R LAD
行数: 147

このように、まず対象日とチームを絞り込むと、その日の対象試合を探しやすくなります。

5. game_pkとは?

game_pkは、MLBの試合を識別するためのIDです。

試合単位でデータを取得するときに重要になります。

まず対象試合を一覧にします。

games = (
    dodgers_data[
        [
            "game_date",
            "game_pk",
            "away_team",
            "home_team"
        ]
    ]
    .drop_duplicates()
    .sort_values("game_pk")
)

display(games)

出力結果

index game_date game_pk away_team home_team
82 2025-06-16 00:00:00 777490 SD LAD

ここで対象試合とgame_pkを確認できます。

game_pkは手作業で適当に入力するのではなく、まず取得したStatcastデータから確認するのがおすすめです。

6. statcast_single_game()で1試合を取得する

pybaseballには、特定の1試合のStatcastデータを取得するstatcast_single_game()があります。

from pybaseball import statcast_single_game

game_data = statcast_single_game(game_pk=777490)

display(game_data.head())

出力結果

index pitch_type game_date release_speed release_pos_x release_pos_z player_name batter pitcher events description spin_dir spin_rate_deprecated break_angle_deprecated break_length_deprecated zone des game_type stand p_throws home_team
206 FF 2025-06-16 00:00:00 93.5 -2.44 5.35 Wade, Tyler 642180 489446 field_out hit_into_play NaN NaN NaN NaN 2 Tyler Wade pops out to third baseman Max Muncy. R L R LAD
217 FS 2025-06-16 00:00:00 86.7 -2.47 5.17 Wade, Tyler 642180 489446 NaN called_strike NaN NaN NaN NaN 13 NaN R L R LAD
219 FF 2025-06-16 00:00:00 93.0 -2.46 5.21 Wade, Tyler 642180 489446 NaN foul NaN NaN NaN NaN 3 NaN R L R LAD
227 FS 2025-06-16 00:00:00 85.9 -2.39 5.18 Iglesias, Jose 578428 489446 field_out hit_into_play NaN NaN NaN NaN 9 Jose Iglesias lines out to shortstop Mookie Betts. R R R LAD
237 FF 2025-06-16 00:00:00 93.4 -2.35 5.38 Iglesias, Jose 578428 489446 NaN foul NaN NaN NaN NaN 11 NaN R R R LAD
1試合
 ↓
多数の投球
 ↓
多数のDataFrame行

という構造です。

7. 取得した試合の基本情報を確認する

display(
    game_data[
        [
            "game_date",
            "game_pk",
            "away_team",
            "home_team"
        ]
    ].drop_duplicates()
)

print("投球数:", len(game_data))

出力結果

index game_date game_pk away_team home_team
206 2025-06-16 00:00:00 777490 SD LAD
投球数: 297

これで、試合日、対戦カード、試合ID、投球数を確認できます。

8. 試合単位の基本サマリーを作る

投球単位のDataFrameを、試合単位の情報に集約してみます。

import pandas as pd

game_summary = pd.DataFrame({
    "項目": [
        "投球数",
        "打球数",
        "平均球速(mph)",
        "平均打球速度(mph)"
    ],
    "値": [
        len(game_data),
        game_data["launch_speed"].notna().sum(),
        game_data["release_speed"].mean(),
        game_data.loc[
            game_data["launch_speed"].notna(),
            "launch_speed"
        ].mean()
    ]
})

display(game_summary)

出力結果

index 項目 値
0 投球数 297.0
1 打球数 104.0
2 平均球速(mph) 92.74410774410775
3 平均打球速度(mph) 82.81346153846152

ここが「試合単位の分析」の基本です。

9. イニング別の投球数を調べる

inning_counts = (
    game_data
    .groupby("inning")
    .size()
    .reset_index(name="pitches")
)

display(inning_counts)

これで、どのイニングに投球が集中していたのかを確認できます。

10. 球種別の投球数を調べる

pitch_counts = (
    game_data
    .groupby("pitch_name")
    .size()
    .reset_index(name="pitches")
    .sort_values("pitches", ascending=False)
)

pitch_counts["usage_percent"] = (
    pitch_counts["pitches"]
    / pitch_counts["pitches"].sum()
    * 100
).round(1)

display(pitch_counts)

出力結果

index pitch_name pitches usage_percent
0 4-Seam Fastball 136 45.8
6 Slider 65 21.9
8 Sweeper 36 12.1
5 Sinker 24 8.1
2 Curveball 13 4.4
3 Cutter 8 2.7
1 Changeup 6 2.0
4 Knuckle Curve 5 1.7
7 Split-Finger 4 1.3

これで、試合中にどの球種が何球投げられたのかを確認できます。

11. 投手ごとの平均球速を調べる

pitcher_speed = (
    game_data
    .groupby("pitcher")
    .agg(
        pitches=("release_speed", "count"),
        avg_speed=("release_speed", "mean")
    )
    .reset_index()
    .sort_values("avg_speed", ascending=False)
)

from pybaseball import playerid_reverse_lookup

pitcher_ids = (
    pitcher_speed["pitcher"]
    .dropna()
    .astype(int)
    .tolist()
)

pitcher_names = playerid_reverse_lookup(
    pitcher_ids,
    key_type="mlbam"
)

pitcher_names = pitcher_names[
    ["key_mlbam", "name_first", "name_last"]
]

pitcher_names["player_name"] = (
    pitcher_names["name_last"]
    + ", "
    + pitcher_names["name_first"]
)

pitcher_speed = pitcher_speed.merge(
    pitcher_names[
        ["key_mlbam", "player_name"]
    ],
    left_on="pitcher",
    right_on="key_mlbam",
    how="left"
)

pitcher_speed = pitcher_speed[
    [
        "pitcher",
        "player_name",
        "pitches",
        "avg_speed"
    ]
]

display(pitcher_speed)

出力結果

index pitcher player_name pitches avg_speed
0 656629 kopech, michael 11 96.89090909090909
1 656945 scott, tanner 7 94.92857142857143
2 656302 cease, dylan 101 94.02574257425744
3 660271 ohtani, shohei 28 93.87857142857142
4 607455 banda, anthony 21 92.66190476190476
5 681911 vesia, alex 8 91.9875
6 593974 peralta, wandy 19 91.93684210526315
7 489446 yates, kirby 10 91.2
8 688158 morgan, david 30 91.12666666666668
9 676508 casparius, ben 62 90.56612903225808

投球数と平均球速を一緒に見ることで、試合全体の平均よりも具体的な情報を得られます。

12. 4シームの球速を調べる

4シーム・ファストボールは一般的にFFとして記録されます。

four_seam = game_data[
    game_data["pitch_type"] == "FF"
].copy()

four_seam_speed = (
    four_seam
    .groupby(["pitcher"], dropna=False)
    .agg(
        pitches=("release_speed", "count"),
        avg_speed=("release_speed", "mean"),
        max_speed=("release_speed", "max")
    )
    .reset_index()
    .sort_values("avg_speed", ascending=False)
)

from pybaseball import playerid_reverse_lookup

pitcher_ids = (
    pitcher_speed["pitcher"]
    .dropna()
    .astype(int)
    .tolist()
)

pitcher_names = playerid_reverse_lookup(
    pitcher_ids,
    key_type="mlbam"
)

pitcher_names = pitcher_names[
    ["key_mlbam", "name_first", "name_last"]
]

pitcher_names["player_name"] = (
    pitcher_names["name_last"]
    + ", "
    + pitcher_names["name_first"]
)

pitcher_speed = four_seam_speed.merge(
    pitcher_names[
        ["key_mlbam", "player_name"]
    ],
    left_on="pitcher",
    right_on="key_mlbam",
    how="left"
)

pitcher_speed = pitcher_speed[
    [
        "pitcher",
        "player_name",
        "pitches",
        "avg_speed"
    ]
]

display(pitcher_speed)

出力結果

index pitcher player_name pitches avg_speed
0 660271 ohtani, shohei 9 99.05555555555556
1 656302 cease, dylan 49 98.65306122448979
2 656629 kopech, michael 9 97.6888888888889
3 656945 scott, tanner 5 97.26
4 688158 morgan, david 13 96.94615384615385
5 607455 banda, anthony 8 96.6375
6 676508 casparius, ben 29 96.23103448275862
7 489446 yates, kirby 7 93.34285714285714
8 681911 vesia, alex 7 93.10000000000001

13. 打球だけを取り出す

launch_speedが記録されている行を取り出します。

batted_balls = game_data[
    game_data["launch_speed"].notna()
].copy()

display(
    batted_balls[
        [
            "player_name",
            "events",
            "launch_speed",
            "launch_angle",
            "hit_distance_sc"
        ]
    ]
)

出力結果

index player_name events launch_speed launch_angle hit_distance_sc
203 Wade, Tyler field_out 76.0 57.0 182.0
221 Wade, Tyler NaN 59.8 48.0 159.0
235 Iglesias, Jose field_out 98.5 5.0 167.0
237 Iglesias, Jose NaN 81.0 43.0 262.0
255 Iglesias, Jose NaN 78.4 53.0 219.0
257 Iglesias, Jose NaN 66.6 48.0 189.0

ここでは、

  • launch_speed:打球速度
  • launch_angle:打球角度
  • hit_distance_sc:打球飛距離

などを確認できます。

14. 最も速い打球を調べる

hardest_hit = (
    batted_balls
    .sort_values("launch_speed", ascending=False)
)

display(
    hardest_hit[
        [
            "player_name",
            "events",
            "launch_speed",
            "launch_angle",
            "hit_distance_sc"
        ]
    ].head(10)
)

出力結果

index player_name events launch_speed launch_angle hit_distance_sc
16 Hernández, Teoscar field_out 110.3 -3.0 25.0
41 Muncy, Max single 108.2 17.0 309.0
275 Machado, Manny field_out 108.1 -7.0 14.0
32 Edman, Tommy single 105.8 16.0 252.0
78 Edman, Tommy field_out 105.7 -17.0 5.0
74 Ohtani, Shohei double 105.2 17.0 337.0
155 Pages, Andy force_out 104.1 -8.0 13.0
185 Smith, Will single 102.0 2.0 66.0
152 Conforto, Michael NaN 100.2 -3.0 34.0
99 Bogaerts, Xander double 100.1 17.0 319.0

これで、その試合で最も速い打球を確認できます。

15. 大谷翔平選手のデータだけを取り出す

大谷翔平選手のMLBAM IDは660271です。

OHTANI_ID = 660271

ohtani_data = game_data[
    game_data["batter"].astype(str) == str(OHTANI_ID)
].copy()

display(ohtani_data.head())

出力結果

index pitch_type game_date release_speed release_pos_x release_pos_z player_name batter pitcher events description spin_dir spin_rate_deprecated break_angle_deprecated break_length_deprecated zone des game_type stand p_throws home_team
108 SL 2025-06-16 00:00:00 87.1 -2.38 5.28 Ohtani, Shohei 660271 688158 walk ball NaN NaN NaN NaN 13 Shohei Ohtani walks. R L R LAD
109 CU 2025-06-16 00:00:00 84.1 -1.71 5.59 Ohtani, Shohei 660271 688158 NaN ball NaN NaN NaN NaN 14 NaN R L R LAD
113 FF 2025-06-16 00:00:00 97.3 -2.06 5.44 Ohtani, Shohei 660271 688158 NaN ball NaN NaN NaN NaN 11 NaN R L R LAD
119 FF 2025-06-16 00:00:00 96.4 -2.06 5.43 Ohtani, Shohei 660271 688158 NaN ball NaN NaN NaN NaN 11 NaN R L R LAD
122 CU 2025-06-16 00:00:00 83.2 -1.84 5.58 Ohtani, Shohei 660271 688158 NaN swinging_strike NaN NaN NaN NaN 14 NaN R L R LAD

これで、その試合における大谷翔平選手の打席に関連する投球データを抽出できます。

16. 大谷翔平選手が見た球を確認する

ohtani_pitches = (
    ohtani_data[
        [
            "game_date",
            "inning",
            "at_bat_number",
            "pitch_number",
            "pitch_name",
            "release_speed",
            "events",
            "description"
        ]
    ]
    .sort_values(
        ["at_bat_number", "pitch_number"]
    )
)

display(ohtani_pitches)

出力結果

index game_date inning at_bat_number pitch_number pitch_name release_speed events description
291 2025-06-16 00:00:00 1 6 1 Slider 89.0 NaN ball
277 2025-06-16 00:00:00 1 6 2 4-Seam Fastball 99.5 NaN called_strike
271 2025-06-16 00:00:00 1 6 3 Slider 90.6 NaN called_strike
261 2025-06-16 00:00:00 1 6 4 Slider 90.4 NaN ball
250 2025-06-16 00:00:00 1 6 5 Slider 91.4 NaN foul
241 2025-06-16 00:00:00 1 6 6 Slider 91.3 NaN ball
230 2025-06-16 00:00:00 1 6 7 Slider 92.4 strikeout swinging_strike
76 2025-06-16 00:00:00 3 22 1 Slider 92.1 NaN blocked_ball
74 2025-06-16 00:00:00 3 22 2 Slider 91.5 double hit_into_play
31 2025-06-16 00:00:00 4 36 1 4-Seam Fastball 99.5 NaN foul
30 2025-06-16 00:00:00 4 36 2 4-Seam Fastball 98.3 single hit_into_play
213 2025-06-16 00:00:00 6 53 1 Slider 88.7 NaN swinging_strike
209 2025-06-16 00:00:00 6 53 2 Sinker 96.1 NaN called_strike
195 2025-06-16 00:00:00 6 53 3 Slider 88.8 NaN blocked_ball
189 2025-06-16 00:00:00 6 53 4 Sinker 95.4 strikeout swinging_strike
122 2025-06-16 00:00:00 8 69 1 Curveball 83.2 NaN swinging_strike
119 2025-06-16 00:00:00 8 69 2 4-Seam Fastball 96.4 NaN ball
113 2025-06-16 00:00:00 8 69 3 4-Seam Fastball 97.3 NaN ball
109 2025-06-16 00:00:00 8 69 4 Curveball 84.1 NaN ball
108 2025-06-16 00:00:00 8 69 5 Slider 87.1 walk ball

これを見ると、何回の打席で何球目にどの球種が投げられたか、その結果どうなったかを確認できます。

17. 大谷翔平選手への球種割合を調べる

ohtani_pitch_usage = (
    ohtani_data
    .groupby("pitch_name")
    .size()
    .reset_index(name="pitches")
    .sort_values("pitches", ascending=False)
)

ohtani_pitch_usage["usage_percent"] = (
    ohtani_pitch_usage["pitches"]
    / ohtani_pitch_usage["pitches"].sum()
    * 100
).round(1)

display(ohtani_pitch_usage)

出力結果

index pitch_name pitches usage_percent
3 Slider 11 55.0
0 4-Seam Fastball 5 25.0
1 Curveball 2 10.0
2 Sinker 2 10.0

複数試合を比較すれば、相手投手によって球種配分が変わったか、といった分析にも発展できます。

18. 大谷翔平選手の打球を調べる

ohtani_batted_balls = ohtani_data[
    ohtani_data["launch_speed"].notna()
].copy()

display(
    ohtani_batted_balls[
        [
            "events",
            "pitch_name",
            "release_speed",
            "launch_speed",
            "launch_angle",
            "hit_distance_sc"
        ]
    ]
)

出力結果

index events pitch_name release_speed launch_speed launch_angle hit_distance_sc
30 single 4-Seam Fastball 98.3 87.9 25.0 274.0
31 NaN 4-Seam Fastball 99.5 81.5 69.0 163.0
74 double Slider 91.5 105.2 17.0 337.0
250 NaN Slider 91.4 77.2 -32.0 4.0

これで、どの球種を打ったのか、その球の球速、打球速度、打球角度、飛距離、打撃結果などを確認できます。

19. 試合単位のデータを取得する基本テンプレート

from pybaseball import statcast, statcast_single_game

DATE = "2025-06-16"
TEAM = "LAD"

daily_data = statcast(
    DATE,
    DATE,
    team=TEAM
)

games = (
    daily_data[
        [
            "game_date",
            "game_pk",
            "away_team",
            "home_team"
        ]
    ]
    .drop_duplicates()
)

display(games)

GAME_PK = games.iloc[0]["game_pk"]

game_data = statcast_single_game(GAME_PK)

display(
    game_data[
        [
            "game_date",
            "game_pk",
            "away_team",
            "home_team"
        ]
    ].drop_duplicates()
)

print("投球数:", len(game_data))

この形を覚えておけば、別の日の試合を分析するときにも応用できます。

20. まとめ

今回はpybaseballを使って、MLBの1試合分のStatcastデータを取得する方法を紹介しました。

試合情報
 ├─ game_pk
 ├─ 対戦チーム
 └─ 試合日

投球情報
 ├─ 総投球数
 ├─ イニング別投球数
 ├─ 球種別投球数
 └─ 球速

打球情報
 ├─ 打球数
 ├─ 打球速度
 ├─ 打球角度
 └─ 飛距離

選手別分析
 └─ 大谷翔平選手の打席・打球データ

statcast_single_game()を使うことで、1試合を丸ごと取得して、そこから必要な指標を作るという分析ができます。

ポイントは、

日付・チームを指定
        ↓
game_pkを確認
        ↓
statcast_single_game()
        ↓
1試合分の投球データ
        ↓
pandasで集計
        ↓
試合単位の分析

という流れです。

21. 次回の記事

次回の「pybaseball基礎編④」では、今回取得した1試合のデータをさらに細かく分解して、打席単位の分析に進みます。

例えば、

  • 1打席で何球投げられたか
  • 初球は何だったか
  • 何球目で結果が出たか
  • どの球種で打席結果が変わったか
  • 大谷翔平選手の1打席をどう分析するか

といった内容を扱います。

データ参照元

本記事では、MLBのStatcastデータをpybaseballから取得して分析しています。

pybaseballは、Statcastを含む野球データをPythonから扱いやすくするためのライブラリです。

実際にデータを利用・公開する場合は、利用元の最新の規約やデータ提供条件も確認してください。

動作環境

本記事ではGoogle Colabを利用しています。

Pythonとpybaseballのバージョンは、以下のコードで確認できます。

import sys
import pybaseball

print("Python:", sys.version)
print("pybaseball:", pybaseball.__version__)

出力結果

Python: 3.13.15 (main, Aug  6 2026, 11:06:22) [GCC 13.3.0]
pybaseball: 2.2.7

Hugo で構築されています。
テーマ Stack は Jimmy によって設計されています。