· 5 years ago · May 12, 2020, 03:30 AM
1# Import Modules
2import pandas as pd
3import numpy as np
4import os
5from pickle import dump,load
6from datetime import datetime
7
8class eloTable:
9
10 def __init__(self,df):
11 """
12 Constructor for creating an eloTable object
13 """
14
15 # Verify Pandas DataFrame
16 if not isinstance(df,pd.DataFrame):
17 raise NotImplementedError('eloTable object must be a Pandas DataFrame')
18
19 # Copy Constructor Arguments
20 self.df = df
21
22 def display(self):
23 """
24 Quick display of dataframe
25 """
26
27 # Print Out
28 print(self.df)
29
30 def save(self,dir,filename):
31 """
32 Description: Class method to pickle (save) an eloTable object
33
34 Input Arguments:
35 dir -- Directory to write output pickle (.p) file to
36 filename -- Name of output pickle (.p) file
37 """
38
39 # Verify Directory Exists
40 if not os.path.exists(dir):
41 raise OSError('Provided output directory %s does not exist' %(dir))
42
43 # Format filename
44 if not filename.endswith('.p'):
45 filename = filename + '.p'
46
47 # Generate Full File Path
48 file = os.path.join(dir,filename)
49
50 # Check if File Already Exists
51 if os.path.exists(file):
52 print('[%s] %s already exists on the system. Overwriting this file' %(datetime.now(),file))
53 os.remove(file)
54
55 # Create Pickle File
56 dump(self.df,open(file,'wb'))
57
58 def add_player(self,player,elo = 1000):
59 """
60 Description: Method to add new row (Player,Elo) to eloTable object
61
62 Input Arguments:
63 player -- Player's name
64 elo -- Elo rating for new player
65 Default: 1000
66 """
67
68 # Create DataFrame
69 data = {'Player': player,'Elo': elo,'GP': 0,'W': 0,'L':0}
70
71 # Append
72 self.df = self.df.append(data,ignore_index = True)
73
74 def update_elo(self,winners,losers,K = 20):
75 """
76 Description: Update Elo table for a new game
77
78 Input Argument(s):
79 winners -- List of game winners
80 losers -- List of game losers
81 """
82
83 def probability(a,b):
84 return 1.0 * 1.0 / (1 + 1.0 * 10**(1.0 * (a - b) / 400.0))
85
86 # Account for New Players
87 for player in (winners + losers):
88 if player not in self.df.values:
89 self.add_player(player)
90
91 # Get Elo Values for Both Teams
92 ra = np.mean(self.df.loc[self.df.Player.isin(winners),'Elo'])
93 rb = np.mean(self.df.loc[self.df.Player.isin(losers),'Elo'])
94
95 # Compute Probabilities
96 ea = probability(rb,ra)
97 eb = probability(ra,rb)
98
99 # Update Elo for Inidividuals
100 self.df.loc[self.df.Player.isin(winners),'Elo'] = round(self.df.loc[self.df.Player.isin(winners),'Elo'] + K * (1.0 - ea))
101 self.df.loc[self.df.Player.isin(losers),'Elo'] = round(self.df.loc[self.df.Player.isin(losers),'Elo'] + K * (0.0 - eb))
102
103 self.df.loc[self.df.Player.isin(winners + losers),'GP'] = self.df.loc[self.df.Player.isin(winners + losers),'GP'] + 1
104 self.df.loc[self.df.Player.isin(winners),'W'] = self.df.loc[self.df.Player.isin(winners),'W'] + 1
105 self.df.loc[self.df.Player.isin(losers),'L'] = self.df.loc[self.df.Player.isin(losers),'L'] + 1
106
107def load_pickle(file):
108 """
109 Description: Function to load pickle (.p) file
110
111 Input Argument(s):
112 file -- Absolute file path to pickle (.p) file
113
114 Output:
115 e -- Object
116 """
117
118 # Verify Existence of File
119 if not os.path.exists(file):
120 raise OSError('Provided output directory %s does not exist' %(file))
121
122 # Verify if Pickle File
123 if not file.endswith('.p'):
124 raise OSError('Provided file does not appear to be a pickle (.p) file')
125
126 # Load Pickle
127 df = load(open(file,'rb'))
128
129 # Generate Object
130 e = eloTable(df)
131
132 # Return
133 return e