Function works normally in vs code. But is giving error when ran on streamlit app

Viewed 15

Iam currently working to make a streamlit app for baseball sabermetrics using pybaseball. I have written a custom function to display pitching stats based upon the pitch type. Here it is :

def stats_by_pitchtypes(df):
    v = df.events.fillna("None").unique()
    u = ["walk","strikeout","single","double","triple","home_run","sac_fly","None"]
    df1 = pd.get_dummies(df.events.fillna("None")).assign(pitch_type = df.pitch_type)
    for i in u:
        if i not in df1.columns:
            df1[i] = 0
    df1 = pd.concat([df1.groupby(["pitch_type"]).sum().assign(
        PT_per = df.pitch_type.value_counts(normalize = True).round(2)*100).assign(
        atbats = lambda x : x.drop(columns = "PT_per").sum(axis = 1).round(3),
        Hits = lambda x : x.drop(columns = ["None","PT_per","atbats","strikeout"]).sum(axis = 1).round(3),
        BA = lambda x : (x.Hits/x.atbats).round(3),
        Total_bases = lambda x : (1*x.single+2*x.double+3*x.triple+4*x.home_run).round(3),
        SLG = lambda x : (x.Total_bases/x.atbats).round(3),
        OBP = lambda x : ((x.walk+x.Hits)/(x.walk+x.Hits+x.sac_fly)).round(4),
        HR_per_AB = lambda x : (x.home_run/x.atbats).round(3),
        ISO = lambda x : ((1*x.double+2*x.triple+3*x.home_run)/x.atbats).round(3),
        BABIP = lambda x : ((x.Hits-x.home_run)/(x.atbats-x.strikeout-x.home_run-x.sac_fly)).round(2),
        HR_per_FB = lambda x : (x.home_run/pd.get_dummies(df.bb_type,
        ).assign(pitch_type = df.pitch_type).groupby(
        "pitch_type").sum().loc["fly_ball"])
    ),pd.get_dummies(df.bb_type).assign(
    pitch_type = df.pitch_type
    ).groupby("pitch_type").sum().transform(lambda x : x/x.sum(), axis = 1).round(2)*100],axis = 1).assign(
       IP = df.groupby("pitch_type")["inning"].apply(IP_cal)  
        ).assign(Kby9 = lambda x : (x.strikeout*9)/x.IP,
        WHIP = lambda x : (x.walk+x.single+x.double+x.triple+x.home_run)/x.IP)
    cols = ["PT_per","BA","SLG","OBP","fly_ball","ground_ball",
    "line_drive","popup","HR_per_AB","HR_per_FB","BABIP","ISO","Kby9","WHIP"]
    return df1.loc[:,cols]

This is giving error when i ran the streamlit app. But when i use the app in the VS code on the same pitcher dataset.Itsnt giving a key error of flyball.

Here is the datset :

start_date = "2008-09-09"
end_date = "2021-09-09"
pitcher1 = "Jeremy Accardo"
pitcher1_df = pb.statcast_pitcher(player_id = pb.playerid_lookup(pitcher1.split(" ")[1],pitcher1.split(" ")[0])["key_mlbam"].values[0],
                start_dt = start_date, end_dt = end_date).replace(pt_dict)
stats_by_pitchtypes(pitcher1_df)

Here is the error in Streamlit : Streamlit error Here is the output in vs code :

VS Code output

can someone debug it why its giving a key error of flyball

1 Answers

This:

"pitch_type").sum().loc["fly_ball"])

Should be this:

"pitch_type").sum().loc[:, "fly_ball"])

This is a good argument for why getting overly fancy with assign can trip up debugging and make your code far less readable.

This is exactly the same as what you have... only if I run into any errors along the way, I'll know exactly where to go to fix the bug!

Sure, it's longer... but read-able and debug-able code > short unnecessarily confusing code that doesn't give helpful error messages.

import pybaseball as pb

def stats_by_pitchtypes(df):
    u = ["walk","strikeout","single",
         "double","triple","home_run",
         "sac_fly","None"]
    df1 = pd.concat([df.pitch_type, 
                     pd.get_dummies(df.events.fillna('None'))],
                    axis=1)
    df1[[i for i in u if i not in df1.columns]] = 0
    df1 = df1.groupby("pitch_type").sum()
    cols = set(df1.columns)
    df1['PT_per'] = (df.pitch_type
                       .value_counts(normalize=True)
                       .round(2)
                       .mul(100))
    df1['atbats'] = (df1[[*cols]]
                        .sum(1)
                        .round(3))
    df1['Hits'] = (df1[[*cols - {'None', 'strikeout'}]]
                      .sum(1)
                      .round(3))
    df1['BA'] = (df1.Hits
                    .div(df1.atbats)
                    .round(3))
    df1['Total_bases'] = sum(df1[x]*(i+1) 
                             for i, x in 
                             enumerate(('single', 'double',
                                        'triple', 'home_run')))
    df1['SLG'] = (df1.Total_bases
                     .div(df1.atbats)
                     .round(3))
    df1['OBP'] = (df1.walk
                     .add(df1.Hits)
                     .div(df1[['walk', 'Hits', 'sac_fly']].sum(1))
                     .round(4))
    df1['HR_per_AB'] = (df1.home_run
                           .div(df1.atbats)
                           .round(3))
    df1['ISO'] = (sum(df1[x]*(i+1) 
                      for i, x in 
                      enumerate(('double', 'triple', 'home_run')))
                      .div(df1.atbats)
                      .round(3))
    df1['BABIP'] = (df1.Hits
                       .sub(df1.home_run)
                       .div(df1.atbats
                               .sub(df1[['strikeout', 'home_run', 'sac_fly']].sum(1)))
                       .round(2))
    df1 = (pd.concat([df1, 
                      pd.concat([df.pitch_type.fillna('None'), 
                                 pd.get_dummies(df.bb_type)], 
                                axis=1)
                        .groupby('pitch_type')
                        .sum()
                        .transform(lambda x: x/x.sum(), axis=1)
                        .round(2)
                        .mul(100)], 
                     axis=1))
    df1['HR_per_FB'] = (df1.home_run
                           .div(df1.fly_ball))
    #df1['IP'] = df.groupby("pitch_type")["inning"].apply(IP_cal)
    #df1['Kby9'] = (df1.strikeout
    #                  .mul(9)
    #                  .div(df1.IP))
    #df1['WHIP'] = (df1[['walk', 'single', 
    #                    'double', 'triple',
    #                    'home_run']]
    #                  .sum(1)
    #                  .div(df1.IP))
    cols = ["PT_per","BA","SLG","OBP",
            "fly_ball","ground_ball",
            "line_drive","popup","HR_per_AB",
            "HR_per_FB","BABIP", "ISO",
    #       "Kby9","WHIP"
           ]
    return df1[cols]

start_date = "2008-09-09"
end_date = "2021-09-09"
pitcher1 = "Jeremy Accardo"
player_id = (pb.playerid_lookup(*pitcher1.split(" ")[::-1])
               ["key_mlbam"]
               .values[0])
df = pb.statcast_pitcher(player_id=player_id,
                         start_dt=start_date,
                         end_dt=end_date)

stats_by_pitchtypes(df)

Output:

            PT_per     BA    SLG     OBP  fly_ball  ground_ball  line_drive  popup  HR_per_AB  HR_per_FB  BABIP    ISO
pitch_type
CH            17.0  0.232  0.116  0.9744      35.0         45.0        17.0    3.0      0.009   0.085714   0.25  0.041
FC            10.0  0.206  0.074  0.9767      21.0         41.0        18.0   21.0      0.005   0.047619   0.21  0.026
FF            49.0  0.204  0.095  0.9867      34.0         43.0        20.0    3.0      0.004   0.117647   0.21  0.036
IN             1.0  0.273  0.000  1.0000       NaN          NaN         NaN    NaN      0.000        NaN   0.27  0.000
PO             0.0  0.000  0.000     NaN       NaN          NaN         NaN    NaN      0.000        NaN   0.00  0.000
SI            10.0  0.221  0.095  1.0000      14.0         62.0        24.0    0.0      0.000   0.000000   0.23  0.015
SL            13.0  0.192  0.102  1.0000      33.0         33.0        26.0    7.0      0.008   0.060606   0.19  0.037
None           NaN    NaN    NaN     NaN      28.0         48.0        18.0    6.0        NaN        NaN    NaN    NaN
Related