Skip to content

Instantly share code, notes, and snippets.

@micahmelling
Created July 4, 2025 02:15
Show Gist options
  • Select an option

  • Save micahmelling/44c760da26d4a50fb95b84cc7fd3764c to your computer and use it in GitHub Desktop.

Select an option

Save micahmelling/44c760da26d4a50fb95b84cc7fd3764c to your computer and use it in GitHub Desktop.
import pandas as pd
from scipy.stats import norm
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(42)
pd.set_option('display.max_rows', None)
pd.set_option('display.max_columns', None)
pd.set_option('display.width', None)
df = pd.DataFrame({
"player": [
"Salvador Perez",
"Vinnie Pasquantino",
"Bobby Witt Jr",
"Maikel Garcia",
"Jonathan India",
"Kyle Isbel",
"Drew Waters",
"Michael Massey",
"Freddy Fermin",
],
"actual_ops": [
656,
738,
825,
846,
664,
642,
615,
479,
654
],
"ops_expectation": [
740,
760,
925,
700,
740,
650,
625,
700,
675
],
"ops_std": [
60,
60,
50,
50,
50,
40,
40,
40,
40
]
})
def get_prob_less_than_or_equal(mean, std_dev, val):
return norm.cdf(val, loc=mean, scale=std_dev)
for index, row in df.iterrows():
prob = get_prob_less_than_or_equal(row['ops_expectation'], row['ops_std'], row['actual_ops'])
df.loc[index, 'prob'] = prob
random_values = np.random.normal(loc=row['ops_expectation'], scale=row['ops_std'], size=100)
random_values = [int(i) for i in random_values]
for i, v in enumerate(random_values):
prob = get_prob_less_than_or_equal(row['ops_expectation'], row['ops_std'], v)
df.loc[index, f'prob_{i}'] = prob
df = df.set_index(keys=["player"])
df = df.round(3)
df.loc['mean'] = df.mean()
df = df.reset_index(drop=False)
print(df)
print()
df.to_csv('data.csv', index=False)
plot_df = df.tail(1).drop(labels=['player', 'actual_ops', 'ops_expectation', 'ops_std'], axis=1)
x = range(len(plot_df.columns))
y = plot_df.iloc[0]
plt.scatter(x[0], y[0], color='red', label='2025 actual')
plt.scatter(x[1:], y[1:], color='blue')
plt.axhline(y.mean(), color='green', linestyle='--', label='Average')
plt.yticks([0, 0.25, 0.50, 0.75, 1])
plt.xlabel('simulation run #')
plt.ylabel('average player probability')
plt.legend()
plt.title('Average Probability of Player OPS Ceiling')
plt.savefig('royals_sim_prob.png')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment