def __init__(self, gm, RoP, main=0): self.fontsize = 10 self.col_w = 8 self.bt_h = 2 self.bt_w = 10 self.paddingx = 5 self.paddingy = 5 self.RoP = RoP if isinstance(RoP, int) else (1 if 'playoff' in RoP else 0) self.gm = gm[:-7] if '.pickle' in gm else gm self.month = int(gm[4:6]) self.season = int(gm[:4]) - 1 if self.month < 9 else int(gm[:4]) game = LoadPickle('D:/sunyiwu/stat/data/seasons_boxscores/%d_%d/%s/%s_boxscores.pickle' % (self.season, self.season + 1, 'playoff' if self.RoP else 'regular', self.gm)) [self.roadteam, self.hometeam] = [x for x in game[0].keys()] self.res = game[0] self.tbs = game[1:] self.columns = None if not main: self.wd_gm = Toplevel() else: self.wd_gm = Tk() self.wd_gm.title('单场比赛') self.wd_gm.iconbitmap('D:/sunyiwu/stat/images/nbahalfcourt.ico') self.wd_gm.geometry('+250+100') self.frame_btn = None self.trees = [] # 存放主客队各一个数据表格 self.ts = 0 self.pm2pn = LoadPickle('D:/sunyiwu/stat/data/playermark2playername.pickle')
def __init__(self, pm, RoP, csv=False): # 构造参数:球员唯一识别号,常规赛or季后赛('regular' or 'playoff') # print(pm) self.pm = pm self.RoP = 0 if RoP == 'regular' else 1 if not csv: plyrdr = 'D:/sunyiwu/stat/data/players/%s/%sGames/%sGameBasicStat.pickle' % ( pm, RoP, RoP) if os.path.exists(plyrdr): self.dt = regular_items_en if not self.RoP else playoff_items_en self.ucgd_its = [12, 13] # unchanged_items 前几列数据项雷打不动 self.exists = True self.plyrFD = plyrdr # 球员个人文件目录 self.data = LoadPickle(self.plyrFD) if not isinstance(self.data, list): self.data = self.data.reset_index(drop=True) if len(self.data.columns) == len(self.dt): self.data.columns = list(self.dt.keys()) else: self.data.columns[:self.ucgd_its[self.RoP]] = list( self.dt.keys())[:self.ucgd_its[self.RoP]] self.cols = list(self.data.columns) # print(self.pm, self.cols) self.seasons = np.sum(self.data['G'] == '1') # 赛季数 self.games = self.data['G'].notna().shape[0] else: self.exists = False
def __init__(self): self.fontsize = 10 self.col_w = 15 self.radiobutton_w = 5 self.paddingx = 10 self.paddingy = 8 self.pm2pn = LoadPickle('../data/playermark2playername.pickle') self.pn2pm = dict(zip(self.pm2pn.values(), self.pm2pn.keys())) self.RoP_dict = {'regular': '常规赛', 'playoff': '季后赛'} self.wd_ = Tk() self.wd_.title('球员数据查询器') self.wd_.iconbitmap('../images/nbahalfcourt.ico') # wd.resizable(width=True, height=True) self.wd_.geometry('+500+20') self.stats_setting = {} # 保存查询条件设置 self.plyr_ent_value = StringVar() self.plyr_ent_value.set('LeBron James') self.RoP = StringVar() self.RoP.set(None) self.AoS = StringVar() self.AoS.set(None) self.scope = StringVar() self.PON = StringVar() self.PON.set('yes') self.wd = Frame(self.wd_) self.wd.grid() self.wd_.bind("<Return>", self.search_enter) self.plyr = None self.plyr_ent = None
def __init__(self): self.fontsize = 10 self.font = ('SimHei', self.fontsize) self.col_w = 15 self.radiobutton_w = 5 self.paddingx = 10 self.paddingy = 10 self.pm2pn = LoadPickle('../data/playermark2playername.pickle') self.pn2pm = dict(zip(self.pm2pn.values(), self.pm2pn.keys())) self.ROP_dict = {'regular': '常规赛', 'playoff': '季后赛'} self.wd_ = Tk() self.wd_.title('比赛数据查询器') self.wd_.iconbitmap('../images/nbahalfcourt.ico') # wd.resizable(width=True, height=True) self.wd_.geometry('+500+20') self.comboboxs = [] self.stats = [] self.season = StringVar() self.ROP = StringVar() self.ROP.set(None) self.qtr = StringVar() self.qtr.set('whole') self.sels = [] self.wd = Frame(self.wd_) self.wd.grid() self.wd_.bind("<Return>", self.search_enter) self.radioframe = None
def __init__(self, startYear, ROP): self.ROP = 'playoffs' if ROP == 'playoff' else ROP filename = 'seasonRegularSummary.pickle'\ if ROP == 'regular'\ else 'seasonPlayoffSummary.pickle' self.gamelist = LoadPickle('./data/seasons/%d_%d/%s' % (startYear, startYear + 1, filename)) self.gameNos = len(self.gamelist) - 1
def search_by_career(self, stats, ave=1): c = LoadPickle('../data/players/%s/%sGames/%sSaCAaS.pickle' % (self.pm, 'playoff' if self.RoP else 'regular', 'playoff' if self.RoP else 'regular')) resL = list(c.values[-2:][ave - 1]) sentence = self.special_filter(resL, stats) if sentence and eval(sentence): return [resL] else: return []
def display_pbp(self): gm = self.gm.get() if gm: try: self.gameflow = LoadPickle(gameMarkToDir(gm, 'regular')) self.file_name = gameMarkToDir(gm, 'regular') except: self.gameflow = LoadPickle(gameMarkToDir(gm, 'playoff')) self.file_name = gameMarkToDir(gm, 'playoff') try: box = LoadPickle(gameMarkToDir(gm, 'regular', tp=2)) except: box = LoadPickle(gameMarkToDir(gm, 'playoff', tp=2)) # self.columns[1], self.columns[5] = ts[0], ts[1] print(box[0]) self.qtrs = len(self.gameflow) self.qtr_btns = [] for i in range(self.qtrs): self.qtr_btns.append( Radiobutton(self.qtr_fm, text=self.qtr_text[i], value=i, command=self.qtr_dsp, variable=self.qtr, width=10, height=2)) self.qtr_btns[i].grid(row=1, column=i) if self.title == 'play-by-play修改器': self.qtr.set('0') else: self.qtr.set(str(int(self.title[1]) - 1)) self.RoW() self.qtr_dsp(ori=1) else: messagebox.showinfo('提示', '请输入game mark!') pass
def search_by_season(self, stats, ave=1): c = LoadPickle('../data/players/%s/%sGames/%sSaCAaS.pickle' % (self.pm, 'playoff' if self.RoP else 'regular', 'playoff' if self.RoP else 'regular')) tmp, resL, ys = [], [], [] c = list(c.values) t = 0 if ave else 1 for i, x in enumerate(c[:-2]): if i % 2 == t: tmp.append(x) [ys.append(y) for y in self.yieldSeasons(sgames=False)] for i, game in enumerate(tmp): sentence = self.special_filter(game, stats) if sentence and eval(sentence): resL.append(['%s %s' % (pm2pn[self.pm], ys[i]), list(game)]) return resL
def teamsWL(ss, ROP): seasonbsdir = './data/seasons_boxscores/%s/%s/' % (ss, ROP) gms = [x[:-17] for x in os.listdir(seasonbsdir)] pc = {} # key: value '队名': [n, n, ..., n] 列表长度为赛季比赛场次,从0开始累加,胜场+1,负场+0 if ROP == 'playoffs': ot = {} # 记录季后赛对手球队 for gm in gms: bs = LoadPickle(seasonbsdir + gm + '_boxscores.pickle') gr = wl(bs[0]) for i, t in enumerate(gr): if t not in pc: pc[t] = [] # pc[t].append(pc[t][-1] + -1 if i else pc[t][-1] + 1) if pc[t] else pc[t].append(-1 if i else 1) pc[t].append(pc[t][-1] if i else pc[t][-1] + 1) if pc[t] else pc[t].append( 0 if i else 1) # 胜队+1,负队+0 if ROP == 'playoffs': ot = rec_op(gr[0], gr[1], ot) ot = rec_op(gr[1], gr[0], ot) if ROP == 'playoffs': return pc, ot else: return pc
def __init__(self, RoP, start_season, end_season, diffplus=5, diffminus=-5, lastmins='5:00.0'): self.ss = start_season self.es = end_season self.dp = diffplus self.dm = diffminus self.lm = lastmins self.RoP = 0 if RoP == 'regular' else 'playoff' self.pm2pn = LoadPickle('./data/playermark2playername.pickle') self.columns = [ 'score', 'freeThrowPct', 'freeThrowMade', 'freeThrowAttempts', 'twoPtPct', 'twoPtMade', 'twoPtAttempts', 'threePtPct', 'threePtMade', 'threePtAttempts', 'fieldGoalPct', 'fieldGoalMade', 'fieldGoalAttempts', 'twoPtAsted', 'threePtAsted', 'fieldGoalAsted', 'ast 2Pt', 'ast 3Pt', 'eFG%', 'TS%', 'ast score', 'overall score', 'games' ] self.plyrcgs = { } # 用于统计球员关键时刻出战场次(暂时无法统计“隐身”情况,即球员在场但无任何行为记录,因此此数字小于等于实际场次)
else: return pc def find_no1_wl(wl): maxp = 0 maxt = '' for i in wl: tmp = wl[i][0] / (wl[i][0] + wl[i][1]) if tmp > maxp: maxp = tmp maxt = i return maxp, maxt chps = LoadPickle('./data/champions.pickle') op_wl = {} help_defeat_wl = {} diff2topwl = {} for season in tqdm(range(1949, 2020)): ss = '%d_%d' % (season, season + 1) cc = chps[ss] # print(ss) pc = teamsWL(ss, 'regular') wls_reg = {} for tm in pc.keys(): wls_reg[tm] = np.array([pc[tm][-1], len(pc[tm]) - pc[tm][-1]]) no1p, no1t = find_no1_wl(wls_reg) ccp = wls_reg[cc][0] / (wls_reg[cc][0] + wls_reg[cc][1]) diff2topwl[ss] = [cc, ccp, no1t, no1p, ccp - no1p]
sys.path.append('../') import os from tqdm import tqdm import numpy as np import pandas as pd import math from util import gameMarkToSeason, gameMarkToDir, LoadPickle, writeToPickle, read_nba_pbp from klasses.Game import Game from klasses.miscellaneous import MPTime from windows.result_windows import ShowSingleGame import matplotlib.pyplot as plt from scipy.stats.stats import pearsonr pp = [] wp = LoadPickle('D:/sunyiwu/stat/data/winning_point.pickle') sss = wp[1] keys = list(sss) for key in keys: sss[key][0] /= sss[key][-1] sss[key][2] /= sss[key][-1] # ============================================================================= # items = ['pts off tovs', 'pts% off tovs', '2nd chance pts', '2nd chance pts%', # 'pts in the paint', 'pts% in the paint', 'biggest lead', 'biggest lead pts%', # 'longest run', 'longest run pts%', 'eFG%', 'TOV%', 'ORB%', 'FT/FGA', # '2PT %', '2PT FGA%', '2PT PTS%', '2PT ASTed%', # '3PT %', '3PT FGA%', '3PT PTS%', '3PT ASTed%', # 'FT %', 'FTA/FGA', 'FT PTS%'] # chain = {}
class searchByPlyr(object): def __init__(self): self.fontsize = 10 self.col_w = 15 self.radiobutton_w = 5 self.paddingx = 10 self.paddingy = 8 self.pm2pn = LoadPickle('../data/playermark2playername.pickle') self.pn2pm = dict(zip(self.pm2pn.values(), self.pm2pn.keys())) self.RoP_dict = {'regular': '常规赛', 'playoff': '季后赛'} self.wd_ = Tk() self.wd_.title('球员数据查询器') self.wd_.iconbitmap('../images/nbahalfcourt.ico') # wd.resizable(width=True, height=True) self.wd_.geometry('+500+20') self.stats_setting = {} # 保存查询条件设置 self.plyr_ent_value = StringVar() self.plyr_ent_value.set('LeBron James') self.RoP = StringVar() self.RoP.set(None) self.AoS = StringVar() self.AoS.set(None) self.scope = StringVar() self.PON = StringVar() self.PON.set('yes') self.wd = Frame(self.wd_) self.wd.grid() self.wd_.bind("<Return>", self.search_enter) self.plyr = None self.plyr_ent = None def label(self, win, text, fs, w, h, ac): return Label(win, text=text, font=('SimHei', fs), width=w, height=h, anchor=ac) def one_tick_sel(self, win, text, value, w, variable, command): return Radiobutton(win, text=text, value=value, command=command, variable=variable, width=w, height=1) def place_sep(self, win, row, columnspan=12): # 分割线 sep = ttk.Separator(win, orient='horizontal') sep.grid(padx=3, pady=3, row=row, column=0, columnspan=columnspan, sticky='ew') def place_equal_inf(self, row): # 信息数据Frame equal_fm = Frame(self.wd) equal_fm.grid(row=row, column=0, columnspan=12) ls = ['Tm', 'Opp', 'GS', 'RoH', 'WoL'] if self.RoP.get() == 'regular'\ else ['Tm', 'Opp', 'GS', 'RoH', 'WoL', 'Series'] self.place_stat(equal_fm, ls, 'i // 3 + 1', 'i % 3 * 2', type=0) def place_basic(self, row): # 基础数据Frame basic_fm = Frame(self.wd) basic_fm.grid(row=row, column=0, columnspan=12) ls = [ 'PTS', 'TRB', 'AST', 'BLK', 'STL', 'TOV', 'ORB', 'DRB', 'PF', 'MP', 'GmSc', '+/-' ] self.place_stat(basic_fm, ls, 'i // 3 + 1', 'i % 3 * 4') def place_shooting(self, row): # 投篮数据Frame shooting_fm = Frame(self.wd) shooting_fm.grid(row=row, column=0, columnspan=12) ls = ['FG', 'FGA', 'FG%', '3P', '3PA', '3P%', 'FT', 'FTA', 'FT%'] self.place_stat(shooting_fm, ls, 'i // 3 + 1', 'i % 3 * 4') def place_inf(self, row): # 信息比较数据Frame inf_fm = Frame(self.wd) inf_fm.grid(row=row, column=0, columnspan=12) ls = ['G', 'Date', 'Age', 'Diff'] if self.RoP.get() == 'regular'\ else ['G', 'Playoffs', 'G#', 'Diff'] self.place_stat(inf_fm, ls, 'i // 2 + 1', 'i % 2 * 4') def place_stat(self, win, ls, row_, col_, type=1): # type 1:大于小于 0:等于 # ==============查询条件输入框布局==================== for i, k in enumerate(ls): row, col = eval(row_), eval(col_) if type: self.label(win, en2ch[k][0] + ':', self.fontsize, self.col_w, 1, 'e').grid(padx=self.paddingx, pady=self.paddingy, row=row, column=col) ent1, ent2 = Entry(win, width=10), Entry(win, width=10) self.label(win, '-', self.fontsize, self.col_w // 3, 1, 'center').grid(padx=self.paddingx // 2, pady=self.paddingy, row=row, column=col + 2) ent1.grid(row=row, column=col + 1, padx=self.paddingx // 2, pady=self.paddingy) ent2.grid(row=row, column=col + 3, padx=self.paddingx // 2, pady=self.paddingy) self.stats_setting[k] = [ent1, ent2] else: self.label(win, en2ch[k][0] + ':', self.fontsize, 12, 1, 'center').grid(padx=self.paddingx, pady=self.paddingy, row=row, column=col) ent = Entry(win, width=10) ent.grid(row=row, column=col + 1, padx=self.paddingx, pady=self.paddingy) self.stats_setting[k] = eval('[ent1, ent2]') if type else eval( '[ent]') def RoPselection(self): [i.grid_remove() for i in self.wd.grid_slaves()[:-10]] self.place_equal_inf(3) self.place_sep(self.wd, 4) self.place_basic(5) self.place_sep(self.wd, 6) self.place_shooting(7) self.place_sep(self.wd, 8) self.place_inf(9) def AoSselection(self): pass def plyr_or_not(self): # 是否按球员分组 self.plyr['text'] = '最小场数' if self.PON.get() == 'no' else '球员' self.plyr_ent_value.set('1') if self.PON.get( ) == 'no' else self.plyr_ent_value.set('LeBron James') def search_enter(self, event): # 绑定回车键触发搜索函数 self.search() def search(self): # 点击按钮触发搜索函数 if self.stats_setting: stats = {} for k in self.stats_setting.keys(): # 遍历文本框控件,收集查询条件 tp = 1 if en2ch[k][1] == 1 or k == 'WoL' or k == 'MP' else 0 ent_s = self.stats_setting[k] if len(ent_s) == 1: # 相等比较 if ent_s[0].get(): stats[k] = [ ' == "%s" and ' % ent_s[0].get() if tp else ' == %s and ' % ent_s[0].get() ] else: if ent_s[0].get() and ent_s[1].get(): # 大于小于同时存在 stats[k] = [ ' >= "%s" and ' % ent_s[0].get() if tp else ' >= %s and ' % ent_s[0].get(), ' <= "%s" and ' % ent_s[1].get() if tp else ' <= %s and ' % ent_s[1].get() ] elif ent_s[0].get() and not ent_s[1].get(): # 只有大于 stats[k] = [ ' >= "%s" and ' % ent_s[0].get() if tp else ' >= %s and ' % ent_s[0].get() ] elif not ent_s[0].get() and ent_s[1].get(): # 只有小于 stats[k] = [ ' <= "%s" and ' % ent_s[1].get() if tp else ' <= %s and ' % ent_s[1].get() ] if not stats: messagebox.showinfo('提示', '请设置查询条件!') else: if self.PON.get() == 'yes': # 单球员查询 if self.plyr_ent_value.get() not in self.pn2pm.keys(): messagebox.showinfo('提示', '球员姓名不存在!') return player = Player(self.pn2pm[self.plyr_ent_value.get()], self.RoP.get()) if self.scope.get() == '单场比赛': pt = 1 res = player.search_by_game(stats) elif self.scope.get() == '赛季': pt = 2 res = player.search_by_season(stats, int(self.AoS.get())) elif self.scope.get() == '职业生涯': pt = 2 res = player.search_by_career(stats, int(self.AoS.get())) res = [[self.plyr_ent_value.get(), x] for x in res] elif self.scope.get() == '连续比赛': pt = 0 res = player.search_by_consecutive(stats) else: # 按球员分组查询 pt = 0 # start = time.time() # pp = [[x, self.RoP.get(), stats] for x in list(self.pm2pn.keys())] # print(time.time() - start) # pool = ThreadPool(4) # tmp = pool.map(process, pp) # pool.close() # pool.join() # print(time.time() - start) # res = [] # for x in tmp: # if x: # res.append(x) # print(time.time() - start) start = time.time() res = [] min_ = 50 if self.RoP.get() == 'regular' else 5 for p in tqdm(list(self.pm2pn.keys())): player = Player(p, self.RoP.get()) if player.exists and not isinstance( player.data, list) and player.games > min_: if self.scope.get() == '单场比赛': tmp = player.search_by_game( stats, minG=int(self.plyr_ent_value.get())) if tmp: res.append([self.pm2pn[p], tmp]) elif self.scope.get() == '赛季': pt = 2 tmp = player.search_by_season( stats, int(self.AoS.get())) res += tmp elif self.scope.get() == '职业生涯': pt = 2 tmp = player.search_by_career( stats, int(self.AoS.get())) if tmp: tmp = [[self.pm2pn[p], x] for x in tmp] res += tmp elif self.scope.get() == '连续比赛': pt = 0 res += player.search_by_consecutive( stats, minG=int(self.plyr_ent_value.get())) print(time.time() - start) # 处理结果 if res: RP = regular_items_en if self.RoP.get( ) == 'regular' else playoff_items_en win_klass = ShowSingleResults if pt else ShowGroupResults print(win_klass) if pt == 2: win_klass = ShowResults result_window = win_klass(res, list(RP.keys()), self.RoP.get(), detail=False if pt else True, AoS=int(self.AoS.get())) win_title = '%s %s 查询结果(按%s)' % (self.plyr_ent_value.get(), self.RoP_dict[self.RoP.get()], self.scope.get())\ if pt else '%s查询结果(按%s)' % ('常规赛' if self.RoP.get() == 'regular' else '季后赛', self.scope.get()) result_window.title(win_title) num = (len(res) - 2 * pt) if pt != 2 else len(res) result_window.loop('共查询到%d组数据' % num, stats) else: messagebox.showinfo('提示', '未查询到符合条件的数据!') else: messagebox.showinfo('提示', '请选择比赛类型!') def loop(self): # ==============背景图片==================== bg_img = Image.open('../images/james.jpg') bg_img = bg_img.resize( (int(bg_img.size[0] * 0.95), int(bg_img.size[1] * 0.95))) bg_img = cv2.cvtColor(np.asarray(bg_img), cv2.COLOR_RGB2BGR) bg_img = cv2.copyMakeBorder(bg_img, 0, 0, 100, 100, cv2.BORDER_REFLECT_101) bg_img = Image.fromarray(cv2.cvtColor(bg_img, cv2.COLOR_BGR2RGB)) bg_img.putalpha(32) # 透明度 bg_img = ImageTk.PhotoImage(bg_img) Label(self.wd, image=bg_img).place(x=0, y=0, relwidth=1, relheight=1) # ==============球员名称label&entry==================== self.plyr = self.label(self.wd, '球员:', self.fontsize, self.col_w, 1, 'e') self.plyr_ent = Entry(self.wd, width=20, textvariable=self.plyr_ent_value, font=('SimHei', 15)) self.plyr.grid(padx=self.paddingx, pady=self.paddingy, row=1, rowspan=2, column=0) self.plyr_ent.grid(padx=self.paddingx, pady=self.paddingy, row=1, rowspan=2, column=1, columnspan=3) # ==============单球员or多球员单选Frame==================== plyr_fm = Frame(self.wd, height=1) plyr_yes = self.one_tick_sel(plyr_fm, '单球员查询', 'yes', self.radiobutton_w * 2, self.PON, self.plyr_or_not) plyr_no = self.one_tick_sel(plyr_fm, '按球员分组', 'no', self.radiobutton_w * 2, self.PON, self.plyr_or_not) plyr_fm.grid(padx=self.paddingx, pady=self.paddingy, row=1, rowspan=2, column=4, columnspan=3) plyr_yes.grid(row=1, column=0) plyr_no.grid(row=1, column=1) # ==============比赛类型组合选择Frame==================== gametype_fm = Frame(self.wd) rglr_sel = self.one_tick_sel(gametype_fm, '常规赛', 'regular', self.radiobutton_w, self.RoP, self.RoPselection) plyf_sel = self.one_tick_sel(gametype_fm, '季后赛', 'playoff', self.radiobutton_w, self.RoP, self.RoPselection) scope_sel = ttk.Combobox(gametype_fm, width=7, textvariable=self.scope) scope_sel['value'] = ['单场比赛', '赛季', '职业生涯', '连续比赛', '连续赛季'] scope_sel.current(0) ave_sel = self.one_tick_sel(gametype_fm, '场均', '1', 2, self.AoS, self.AoSselection) sum_sel = self.one_tick_sel(gametype_fm, '总和', '0', 2, self.AoS, self.AoSselection) self.AoS.set('1') self.place_sep(gametype_fm, 2, columnspan=2) gametype_fm.grid(padx=self.paddingx, pady=self.paddingy, row=1, rowspan=2, column=7, columnspan=4) rglr_sel.grid(padx=self.paddingx, pady=self.paddingy, row=1, column=0) plyf_sel.grid(padx=self.paddingx, pady=self.paddingy, row=1, column=1) scope_sel.grid(padx=self.paddingx, pady=self.paddingy, row=1, rowspan=3, column=2, columnspan=2) ave_sel.grid(padx=self.paddingx, pady=self.paddingy, row=3, column=0, sticky='e') sum_sel.grid(padx=self.paddingx, pady=self.paddingy, row=3, column=1, sticky='w') # ==============搜索button==================== search_img = Image.open('../images/kobe_dunk.jpg') search_img = ImageTk.PhotoImage(search_img) search_button = Button(self.wd, text='查 询', width=60, height=30, image=search_img, compound='center', cursor='hand2', command=self.search, font=('SimHei', 14)) search_button.grid(padx=self.paddingx, pady=self.paddingy, row=1, rowspan=2, column=11) # ==============说明label==================== self.place_sep(self.wd, 20) notion = self.label(self.wd, '说明:', self.fontsize, self.col_w, 1, 'e') help_note = '主客场:0客1主 比赛序号:赛季第n场比赛\n' \ '年龄:35-001 赛果:W/L 日期:%s\n' \ '季后赛轮次:E/WC1->第一轮,E/WCS->分区半决赛,' \ 'E/WCF->分区决赛,FIN->总决赛' % time.strftime("%Y%m%d") notion_ = Label(self.wd, text=help_note, font=('SimHei', 11), width=self.col_w * 5, height=6, anchor='w', justify='left') notion.grid(padx=self.paddingx, pady=self.paddingy, row=26, column=0) notion_.grid(padx=self.paddingx, pady=self.paddingy, row=26, rowspan=6, column=1, columnspan=11, sticky='w') # wd.attributes("-alpha", 0.8) self.RoP.set('regular') self.RoPselection() self.wd.mainloop()
#%% regularOrPlayoff = 1 ROP = regularOrPlayoffs[regularOrPlayoff] for i in players: print("Analysing player: %s ..." % i[0]) player = Player(i[1], ROP) missing_shot = 0 areaPct = np.zeros((21,3)) #0miss1make for season in player.yieldSeasons(): for gameInf in player.yieldGames(season): gameMark, team = gameInf[1], gameInf[3] # 读取比赛文件 gameDir = gameMarkToDir(gameMark, ROP) gameDir_shot = gameMarkToDir(gameMark, ROP, shot=True) playerGame = LoadPickle(gameDir) playerGame_shot = LoadPickle(gameDir_shot) index_shot = 0 # 判断主客场 HOA = 1 if team == gameMark[-3:] else 0 # 0客1主 HomeOrAt = HomeOrAts[HOA-1] for index, quarter in enumerate(playerGame): for play in quarter: if len(play) == 6: if play[HomeOrAt[1]]: playerPlayed = play[HomeOrAt[1]].split(' ')[0] if playerPlayed == i[1] and (play[HomeOrAt[0]] or 'misses' in play[HomeOrAt[1]]): # 此球员有得分/错失得分 score = 0 diff = play[3] if HOA == 1:
def __init__(self, gm, ROP, HOA=None): self.gamemark = gm self.gameflow = LoadPickle(gameMarkToDir(gm, ROP, shot=True)) self.HOA = HOA if HOA != None else None
class Player(object): def __init__(self, pm, RoP, csv=False): # 构造参数:球员唯一识别号,常规赛or季后赛('regular' or 'playoff') # print(pm) self.pm = pm self.RoP = 0 if RoP == 'regular' else 1 if not csv: plyrdr = 'D:/sunyiwu/stat/data/players/%s/%sGames/%sGameBasicStat.pickle' % ( pm, RoP, RoP) if os.path.exists(plyrdr): self.dt = regular_items_en if not self.RoP else playoff_items_en self.ucgd_its = [12, 13] # unchanged_items 前几列数据项雷打不动 self.exists = True self.plyrFD = plyrdr # 球员个人文件目录 self.data = LoadPickle(self.plyrFD) if not isinstance(self.data, list): self.data = self.data.reset_index(drop=True) if len(self.data.columns) == len(self.dt): self.data.columns = list(self.dt.keys()) else: self.data.columns[:self.ucgd_its[self.RoP]] = list( self.dt.keys())[:self.ucgd_its[self.RoP]] self.cols = list(self.data.columns) # print(self.pm, self.cols) self.seasons = np.sum(self.data['G'] == '1') # 赛季数 self.games = self.data['G'].notna().shape[0] else: self.exists = False def season_index(self, games): # print(type(games['G'][0]), games['G']) return list(games[games['G'] == '1'].index) + [games.shape[0]] def yieldSeasons(self, sgames=True): # 按赛季返回 sgames为False时只返回赛季年号 games = self.on_board_games(self.data) games = games.reset_index(drop=True) ss_ix = self.season_index(games) for i in range(self.seasons): ss = games.iloc[ss_ix[i]]['Playoffs' if self.RoP else 'Date'] yy = ss[:4] yy = '%s_%s' % (str(int(yy) - 1), yy) if self.RoP else '%s_%s' % ( yy, str(int(yy) + 1)) if sgames: yield games[ss_ix[i]:ss_ix[i + 1]], yy else: yield yy def getSeason(self, ss): gmcol = 'Playoffs' if self.RoP else 'Date' start = ss[:4] gms = self.data[self.data['G'].notna()] s, e, flag = -1, -1, 0 for i in gms.index: if not flag and gms[gmcol][i] > start + '10': s = i flag = 1 elif s != -1 and gms['G'][i] == '1': e = i - 1 break res = gms.loc[s:e] if e != -1 else gms.loc[s:] res = res.reset_index(drop=True) return res def on_board_games(self, games): # games = games['G'].astype('str') # games = games[games['G'] != ''] return games[games['G'].notna()] def yieldGames(self, season, del_absent=True): # 按单场比赛返回 if del_absent: season = self.on_board_games(season) for i in season.index: yield season.loc[i] def _get_item(self, item, season_index=None): games = self.data[self.ss_ix[season_index - 1]:self. ss_ix[season_index]] if season_index else self.data return self.on_board_games(games)[item] def seasonAVE(self, ind, item): # 求取赛季平均,传入参数:赛季序号、统计项名称 return np.mean( self._get_item(item, season_index=ind).astype(np.float64)) def average(self, item): return np.mean(self._get_item(item).astype(np.float64)) def seasonSUM(self, ind, item): # 求取赛季平均,传入参数:赛季序号、统计项名称 return np.sum( self._get_item(item, season_index=ind).astype(np.float64)) def sum(self, item): return np.sum(self._get_item(item).astype(np.float64)) def special_filter(self, game, stats): # 按条件筛选每条数据 sentence = '' for k in stats: if en2ch[k][1] == 0: # 数值型 x = float(game[self.dt[k]]) if math.isnan(x): return '' elif en2ch[k][1] == 1: # 字符型 x = '"%s"' % str(game[self.dt[k]]) else: # 特殊处理 if k == 'WoL': x = '"%s"' % game[7 if self.RoP else 6][0] elif k == 'RoH': x = '0' if game[4] == '@' else '1' elif k == 'Date' or k == 'Playoffs': x = '%s' % game[1][:8] elif k == 'MP': tmp = game[9 if self.RoP else 8] if not isinstance(tmp, str): continue if int(tmp[:tmp.index(':')]) < 10: tmp = '0' + tmp # 分钟数小于10前面加0 if len(tmp) == 5: # 没有数秒位 tmp += ':00' x = '"%s"' % tmp else: x = '%d' % int(game[7 if self.RoP else 6][3:-1]) for cmp_i, t in enumerate(stats[k]): sentence += '%s%s' % (x, stats[k][cmp_i]) sentence = sentence[:-5] return sentence def ave_and_sum(self, tmp, type=2): # type=0:计算总和 1:计算均值 2:计算均值和总和 if isinstance(tmp, list): tmp = pd.DataFrame(tmp, columns=regular_items_en.keys() if not self.RoP else playoff_items_en.keys()) if type: ave = [] sumn = [] for k in tmp.columns: if k == 'G': # 首列 if type: ave.append('%d场平均' % tmp.shape[0]) sumn.append('%d场总和' % tmp.shape[0]) elif k in ['Playoffs', 'Date', 'Age', 'Tm', 'Opp', 'Series', 'G#']: if type: ave.append('/') sumn.append('/') elif k == 'RoH': # 统计主客场数量 try: at = np.sum(tmp[k] == '@') except: at = 0 if type: ave.append('%dR/%dH' % (at, tmp.shape[0] - at)) sumn.append('%dR/%dH' % (at, tmp.shape[0] - at)) elif k == 'WoL': # 统计几胜几负 origin = WinLoseCounter(False) for i in tmp[k]: origin += WinLoseCounter(True, strwl=i) if type: ave.append(origin.average()) sumn.append(origin) elif k == 'GS': # 统计首发次数 cs = tmp[k].value_counts() if cs.empty: if type: ave.append('') sumn.append('') else: try: s = np.sum(tmp[k] == '1') except: s = 0 if type: ave.append('%d/%d' % (s, tmp.shape[0])) sumn.append('%d/%d' % (s, tmp.shape[0])) elif k == 'MP': # 时间加和与平均 sum_time = MPTime('0:00.0', reverse=False) for i in tmp[k]: if isinstance(i, str): sum_time += MPTime(i, reverse=False) if type: ave.append(sum_time.average(tmp.shape[0])) sumn.append(sum_time.strtime[:-2]) elif '%' in k: # 命中率单独计算 goal = tmp[[k[:-1], k[:-1] + 'A']] goal = goal.dropna(axis=0, how='any') goal = goal.astype('float').sum(axis=0) p = goal[k[:-1]] / goal[k[:-1] + 'A'] if goal[k[:-1] + 'A'] else float('nan') if not math.isnan(p): p = '%.3f' % p if p != '1.000': p = p[1:] else: p = '' if type: ave.append(p) sumn.append(p) else: tmp_sg = tmp[k][tmp[k].notna()] # tmp_sg = tmp_sg[tmp_sg != ''] if not tmp_sg.empty: if type: # print(tmp_sg) try: a = '%.1f' % tmp_sg.astype('float').mean() except: tmp_sg = tmp_sg[tmp_sg != ''] a = '%.1f' % tmp_sg.astype('float').mean() # 除比赛评分以外其他求和结果均为整数 s = '%.1f' % tmp_sg.astype('float').sum( ) if k == 'GmSc' else int(tmp_sg.astype('int').sum()) if k == '+/-': # 正负值加+号 if type and s != 0 and a[0] != '-': a = '+' + a if s > 0: s = '+%d' % s if s == 'nan': if type: a = '' s = '' else: a, s = '', '' if type: ave.append(a) sumn.append(s) if type == 0: return [sumn] elif type == 1: return [ave] else: return [ave, sumn] def search_by_consecutive(self, stats, minG=2): if minG < 2: minG = 2 # print(stats) resL, tmp = [], [] for ss, ys in self.yieldSeasons(): for game in list(ss.values): sentence = self.special_filter(game, stats) if sentence and eval(sentence): tmp.append(game) else: if len(tmp) >= minG: tmp += self.ave_and_sum(tmp) resL.append(['%s %s' % (pm2pn[self.pm], ys), tmp]) tmp = [] return resL def search_by_season(self, stats, ave=1): c = LoadPickle('../data/players/%s/%sGames/%sSaCAaS.pickle' % (self.pm, 'playoff' if self.RoP else 'regular', 'playoff' if self.RoP else 'regular')) tmp, resL, ys = [], [], [] c = list(c.values) t = 0 if ave else 1 for i, x in enumerate(c[:-2]): if i % 2 == t: tmp.append(x) [ys.append(y) for y in self.yieldSeasons(sgames=False)] for i, game in enumerate(tmp): sentence = self.special_filter(game, stats) if sentence and eval(sentence): resL.append(['%s %s' % (pm2pn[self.pm], ys[i]), list(game)]) return resL def search_by_career(self, stats, ave=1): c = LoadPickle('../data/players/%s/%sGames/%sSaCAaS.pickle' % (self.pm, 'playoff' if self.RoP else 'regular', 'playoff' if self.RoP else 'regular')) resL = list(c.values[-2:][ave - 1]) sentence = self.special_filter(resL, stats) if sentence and eval(sentence): return [resL] else: return [] # def process(self, game, stats): # sentence = self.special_filter(game, stats) # if sentence and eval(sentence): # return game def search_by_game(self, stats, minG=1): if minG < 1: minG = 1 # 可统一比较大小或判断相等 games = self.on_board_games(self.data).values if len(games) >= minG: resL = [] # pool = Pool(processes=4) # multiprocessing.set_start_method('spawn') # for game in games: # res = pool.apply(self.process, (game, stats, )) # if res is not None: # resL.append(res) # pool.close() # pool.join() for game in games: sentence = self.special_filter(game, stats) if sentence and eval(sentence): resL.append(game) if len(resL) < minG: return [] else: resL += self.ave_and_sum(resL) # 求取平均和总和 return resL else: return []
# -*- coding:utf8 -*- import sys sys.path.append('../') from util import LoadPickle, playerMarkToDir from klasses.miscellaneous import MPTime from klasses.Player import Player from klasses.Game import Game import pandas as pd import numpy as np from tqdm import tqdm pd.options.display.expand_frame_repr = False pd.options.display.width = 50 RoF = ['regular', 'playoff'] pm2pn = LoadPickle('./data/playermark2playername.pickle') plyr_ss = LoadPickle('./data/playerSeasonAverage.pickle') # 球员所在球队及对手球队赛季场均数据 lg_ss = LoadPickle('./data/leagueSeasonAverage.pickle') # 联盟球队赛季场均数据 games_td = [30, 5] tartext = ['Steal', 'Turnover', 'Block', 'Assist', 'OffReb'] enforce = {} # 球员生涯/赛季数据影响力因子均值(抢断失误盖帽助攻前板) lg_season = {} # 联盟生涯/赛季数据影响力因子均值(抢断失误盖帽助攻前板) for tar_item in range(len(tartext)): # 0抢断1失误2盖帽3助攻4前板 enforce[tartext[tar_item]] = LoadPickle( './data/Enforce/player%sEnforce.pickle' % tartext[tar_item]) lg_season[tartext[tar_item]] = LoadPickle( './data/Enforce/season%sEnforceRecord.pickle' % tartext[tar_item]) # for tar_item in range(len(tartext)): # print(tartext[tar_item], len(enforce[tartext[tar_item]])) pms = list(enforce['Turnover'].keys())
#%% # 0输1赢2总;0全部1投中2投失3全部两分4投中5投失6全部三分7投中8投失 numGames = [] cnt = np.zeros((24, 4, 3, 9)) dis = np.zeros((24, 4, 3, 9)) score = np.zeros((24, 2)) for n, season in enumerate(range(1996, 2020)): gameDir = './data/seasons_shot/%d_%d/%s/' % ( season, season + 1, regularOrPlayoffs[regularOrPlayoff]) upROP = regularOrPlayoffs[regularOrPlayoff][0].upper( ) + regularOrPlayoffs[regularOrPlayoff][1:] summaryDir = './data/seasons/%d_%d/season%sSummary.pickle' % ( season, season + 1, upROP) summary = LoadPickle(summaryDir) numGames.append(len(summary) - 1) print('starting to analysing season %s-%s:' % (season, season + 1)) for game in tqdm(summary[1:]): f = open(gameDir + game[0] + '_shot.pickle', 'rb') c = pickle.load(f) f.close() if season < 2000: win = 0 if int(game[2]) > int(game[4]) else 1 score[n][0] += min(int(game[2]), int(game[4])) score[n][1] += max(int(game[2]), int(game[4])) else: win = 0 if int(game[3]) > int(game[5]) else 1 score[n][0] += min(int(game[3]), int(game[5])) score[n][1] += max(int(game[3]), int(game[5]))
class Search_by_game(object): def __init__(self): self.fontsize = 10 self.font = ('SimHei', self.fontsize) self.col_w = 15 self.radiobutton_w = 5 self.paddingx = 10 self.paddingy = 10 self.pm2pn = LoadPickle('../data/playermark2playername.pickle') self.pn2pm = dict(zip(self.pm2pn.values(), self.pm2pn.keys())) self.ROP_dict = {'regular': '常规赛', 'playoff': '季后赛'} self.wd_ = Tk() self.wd_.title('比赛数据查询器') self.wd_.iconbitmap('../images/nbahalfcourt.ico') # wd.resizable(width=True, height=True) self.wd_.geometry('+500+20') self.comboboxs = [] self.stats = [] self.season = StringVar() self.ROP = StringVar() self.ROP.set(None) self.qtr = StringVar() self.qtr.set('whole') self.sels = [] self.wd = Frame(self.wd_) self.wd.grid() self.wd_.bind("<Return>", self.search_enter) self.radioframe = None def one_tick_sel(self, text, value, command, win): return Radiobutton(win, text=text, value=value, command=command, variable=self.qtr, width=self.radiobutton_w, height=1) def season_cbox_sel(self, event): [i.grid_remove() for i in self.radioframe.grid_slaves()] if self.season.get()[:4] >= '1996': end = 8 elif self.season.get()[:4] < '1983': end = 1 else: end = 2 for ix, i in enumerate(self.sels[:end]): i.grid(padx=self.paddingx, pady=self.paddingy, row=1, column=ix) def search_enter(self, event): # 绑定回车键触发搜索函数 self.search() def search(self): print('功能尚未开放') def timespan(self): pass def ROPselection(self): pass def QTRselection(self): pass def loop(self): # 背景图片 bg_img = Image.open('../images/james2.jpg') bg_img.putalpha(64) bg_img = ImageTk.PhotoImage(bg_img) Label(self.wd, image=bg_img).place(x=0, y=0, relwidth=1, relheight=1) self.radioframe = Frame(self.wd) self.radioframe.grid(padx=self.paddingx, pady=self.paddingy, row=4, column=0, columnspan=5, sticky='ew') # 控件设置 season_label = Label(self.wd, text='赛季:', font=self.font, width=self.col_w, height=1, anchor='e') season_sel = ttk.Combobox(self.wd, width=9, textvariable=self.season) season_sel['value'] = ['%d-%d' % (x, x + 1) for x in range(1949, 2020)] season_sel.current(len(season_sel['value']) - 1) timespan_frame = LabelFrame(self.wd, text='时间跨度', labelanchor="nw") sglssn_sel = self.one_tick_sel('单赛季', 'single_season', self.timespan, timespan_frame) tilnow_sel = self.one_tick_sel('至今', 'tillnow', self.timespan, timespan_frame) rf_frame = LabelFrame(self.wd, text='比赛类型', labelanchor="nw") rglr_sel = self.one_tick_sel('常规赛', 'regular', self.ROPselection, rf_frame) plyf_sel = self.one_tick_sel('季后赛', 'playoff', self.ROPselection, rf_frame) search_img = Image.open('../images/kobe_dunk.jpg') search_img = ImageTk.PhotoImage(search_img) search_button = Button(self.wd, text='查 询', width=65, height=30, image=search_img, compound='center', cursor='hand2', command=self.search, font=('SimHei', 14)) team_label = Label(self.wd, text='球队:', font=self.font, width=self.col_w, height=1, anchor='e') oppteam_label = Label(self.wd, text='对手球队:', font=self.font, width=self.col_w, height=1, anchor='e') team_ent = Entry(self.wd, width=10) oppteam_ent = Entry(self.wd, width=10) sel_texts = [['全场', 'whole'], ['进阶', 'advcd'], ['第一节', '1st'], ['第二节', '2nd'], ['上半场', '1hf'], ['第三节', '3rd'], ['第四节', '4th'], ['下半场', '2hf']] for ts in sel_texts: self.sels.append(self.one_tick_sel(ts[0], ts[1], self.QTRselection, self.radioframe)) # 控件布局 season_label.grid(padx=self.paddingx, pady=self.paddingy, row=1, rowspan=2, column=0) season_sel.grid(padx=self.paddingx, pady=self.paddingy, row=1, rowspan=2, column=1) season_sel.bind("<<ComboboxSelected>>", self.season_cbox_sel) timespan_frame.grid(padx=self.paddingx, pady=self.paddingy, row=1, rowspan=2, column=2) sglssn_sel.grid(padx=self.paddingx, pady=self.paddingy, row=1, column=0) tilnow_sel.grid(padx=self.paddingx, pady=self.paddingy, row=2, column=0) rf_frame.grid(padx=self.paddingx, pady=self.paddingy, row=1, rowspan=2, column=3) rglr_sel.grid(padx=self.paddingx, pady=self.paddingy, row=1, column=0) plyf_sel.grid(padx=self.paddingx, pady=self.paddingy, row=2, column=0) search_button.grid(padx=self.paddingx, pady=self.paddingy, row=1, rowspan=2, column=4, columnspan=2) team_label.grid(padx=self.paddingx, pady=self.paddingy, row=3, column=0) oppteam_label.grid(padx=self.paddingx, pady=self.paddingy, row=3, column=2) team_ent.grid(padx=self.paddingx, pady=self.paddingy, row=3, column=1) oppteam_ent.grid(padx=self.paddingx, pady=self.paddingy, row=3, column=3) # whole_sel.grid(padx=self.paddingx, pady=self.paddingy, row=1, column=2, sticky='ew') # advcd_sel.grid(padx=self.paddingx, pady=self.paddingy, row=1, column=3, sticky='ew') # first_sel.grid(padx=self.paddingx, pady=self.paddingy, row=2, column=0, sticky='ew') # secnd_sel.grid(padx=self.paddingx, pady=self.paddingy, row=2, column=1, sticky='ew') # fsthf_sel.grid(padx=self.paddingx, pady=self.paddingy, row=2, column=2, sticky='ew') # third_sel.grid(padx=self.paddingx, pady=self.paddingy, row=2, column=3, sticky='ew') # forth_sel.grid(padx=self.paddingx, pady=self.paddingy, row=2, column=4, sticky='ew') # sndhf_sel.grid(padx=self.paddingx, pady=self.paddingy, row=2, column=5, sticky='ew') self.wd.mainloop()
def seasonfile(self, sn): file = './data/seasons_RAT/%s.pickle' % sn return LoadPickle(file)
#!/usr/bin/python # -*- coding:utf8 -*- from util import LoadPickle, getCode, writeToPickle import os RoFs = ['regular', 'playoffs'] for season in range(2014, 2020): ss = '%d_%d' % (season, season + 1) print(ss) for i in range(2): season_dir = './data/seasons/%s/%s/' % (ss, RoFs[i]) gms = os.listdir(season_dir) for gm in gms: c = LoadPickle(season_dir + gm) for q, qtr in enumerate(c): for ix, r in enumerate(qtr): if len(r) == 6 and 'enters' in (r[1] if r[1] else r[-1]): ind = 1 if r[1] else 5 tmp = r[ind].split(' ') pm1, pm2 = tmp[0], tmp[-1] if pm1 == pm2: print(gm, c[q][ix][ind]) url = 'https://www.basketball-reference.com/boxscores/pbp/%s.html' % gm[:-7] plays = getCode(url, 'UTF-8') plays = plays.find('table', class_='stats_table').find_all('tr') for play in plays: tdPlays = play.find_all('td') if len(tdPlays) == 6: for p in tdPlays: if p.find_all('a'):
import sys sys.path.append('../') import pandas as pd import os from klasses.stats_items import * from klasses.miscellaneous import MPTime, WinLoseCounter from util import LoadPickle import numpy as np import math import multiprocessing from multiprocessing.pool import Pool pm2pn = LoadPickle('D:/sunyiwu/stat/data/playermark2playername.pickle') class Player(object): def __init__(self, pm, RoP, csv=False): # 构造参数:球员唯一识别号,常规赛or季后赛('regular' or 'playoff') # print(pm) self.pm = pm self.RoP = 0 if RoP == 'regular' else 1 if not csv: plyrdr = 'D:/sunyiwu/stat/data/players/%s/%sGames/%sGameBasicStat.pickle' % ( pm, RoP, RoP) if os.path.exists(plyrdr): self.dt = regular_items_en if not self.RoP else playoff_items_en self.ucgd_its = [12, 13] # unchanged_items 前几列数据项雷打不动 self.exists = True
[[MPTime('0:00.0'), MPTime('0:00.0'), MPTime('0:00.0'), MPTime('0:00.0'), MPTime('0:00.0'), MPTime('0:00.0'), MPTime('0:00.0'), MPTime('0:00.0'), MPTime('0:00.0')], [MPTime('0:00.0'), MPTime('0:00.0'), MPTime('0:00.0'), MPTime('0:00.0'), MPTime('0:00.0'), MPTime('0:00.0'), MPTime('0:00.0'), MPTime('0:00.0'), MPTime('0:00.0')], [MPTime('0:00.0'), MPTime('0:00.0'), MPTime('0:00.0'), MPTime('0:00.0'), MPTime('0:00.0'), MPTime('0:00.0'), MPTime('0:00.0'), MPTime('0:00.0'), MPTime('0:00.0')]]] average_time = [[['', '', '', '', '', '', '', '', ''], ['', '', '', '', '', '', '', '', ''], ['', '', '', '', '', '', '', '', '']], [['', '', '', '', '', '', '', '', ''], ['', '', '', '', '', '', '', '', ''], ['', '', '', '', '', '', '', '', '']]] count_score = np.zeros((2, 3, 9)) ss = '%d_%d' % (season, season + 1) # print(ss) for i in range(2): # 分别统计常规赛、季后赛 gms = os.listdir('D:/sunyiwu/stat/data/seasons/%s/%s/' % (ss, regularOrPlayoffs[i])) for gm in tqdm(gms): count_games[i] += 1 # print('\t\t\t' + gm) game = Game(gm[:-7], regularOrPlayoffs[i]) gameplyrs = game.teamplyrs() record = LoadPickle(gameMarkToDir(gm[:-7], regularOrPlayoffs[i], tp=3)) # _, _, _, record = game.game_scanner(gm[:-7]) zoom = 0 bp = -1 pm = '' for rec in record: if zoom: # 处于抢断/失误观察期内 # 出现得失分 if 'MK' in rec or 'MS' in rec: GoM = 1 if 'MK' in rec else 0 KoS = 'MK' if GoM else 'MS' plyr_side = 0 if pm in gameplyrs[0] else 1 if tar_item: plyr_side = 0 if plyr_side else 1 sp = rec[KoS][0] if sp in gameplyrs[plyr_side]:
# 85-86赛季开始由执法裁判记录 # 94-95赛季开始记录比赛总时长 import os import pandas as pd from bs4 import BeautifulSoup from tqdm import tqdm from util import getCode, writeToPickle, LoadPickle import re import time for season in range(2020, 2021): refs = LoadPickle('./data/refereeURLs.pickle') res = [] # [gm, Referees, Attendance, Time of Game] ss = '%d_%d' % (season-1, season) # 赛季 print('=' * 50 + '\nstarting to record season %s' % ss) seasondir = './data/seasons/%s/' % ss for RoP in ['Regular', 'Playoff']: tb = LoadPickle(seasondir + 'season%sSummary.pickle' % RoP) for gm in tqdm(tb[1:]): if gm[0] in ['195101140PHW']: res.append([gm[0], '', 6665, '']) elif gm[0] in ['197511260LAL']: continue else: gameURL = 'https://www.basketball-reference.com/boxscores/%s.html' % gm[0] gamePage = getCode(gameURL, 'UTF-8') # s = time.time()) # q = gamePage.find('div', id='content').find_all('strong') # print(time.time() - s)
def __init__(self, RoP): self.dir = './data/seasons_RAT/' self.plyrs = LoadPickle('./data/playerBasicInformation.pickle') self.RoP = RoP
#!/usr/bin/python # -*- coding:utf8 -*- from klasses.Player import Player from util import LoadPickle, writeToPickle from klasses.stats_items import * from tqdm import tqdm import pandas as pd # 计算球员赛季和生涯场均及总和并保存 pm2pn = LoadPickle('../data/playermark2playername.pickle') for p in tqdm(list(pm2pn.keys())): # print(p) for RoP in ['regular', 'playoff']: player = Player(p, RoP) if player.exists and not isinstance(player.data, list): res = [] for sss, ss in player.yieldSeasons(): sss = player.on_board_games(sss) res += player.ave_and_sum(sss, type=2) res[-2] = [ss] + res[-2] res[-1] = [ss] + res[-1] sss = player.on_board_games(player.data) res += player.ave_and_sum(sss, type=2) res[-2] = ['career'] + res[-2] res[-1] = ['career'] + res[-1] res = pd.DataFrame(res, columns=['Season'] + list(regular_items_en.keys() if RoP == 'regular' else playoff_items_en.keys())) # for col in res.columns: # res[col] = res[col].astype('category')
import os from tqdm import tqdm import numpy as np from klasses.Game import Game from klasses.miscellaneous import MPTime from util import writeToPickle, gameMarkToDir, LoadPickle, plus_minus from splitLineups import splitLineups regularOrPlayoffs = ['regular', 'playoff'] def inline(r): line = r['R'][RoH] return sorted(line, reverse=True) lines_all = LoadPickle('./data/Lineups/anaSeason5Lineups.pickle') for season in range(2020, 2021): ss = '%d_%d' % (season, season + 1) for i in range(2): lines_all[i][ss] = {} lines = { } # {'tm1': {'line1': ['sum_time', '+/-'], 'line2': ['sum_time', '+/-'] ...}, 'tm2': ...} gms = os.listdir('D:/sunyiwu/stat/data/seasons/%s/%s/' % (ss, regularOrPlayoffs[i])) for gm in tqdm(gms): game = Game(gm, regularOrPlayoffs[i]) record = LoadPickle(gameMarkToDir(gm, regularOrPlayoffs[i], tp=3)) rot = game.rotation(record) bxs, rot = game.replayer(record, rot) et = '%d:00.0' % (48 + 5 * (game.quarters - 4)) for tmix, tm in enumerate(list(game.bxscr[0])): # 分别回溯两支球队
for ix, combs_i in enumerate( pms1234): # 遍历1-4人的所有搭配,累加时间和正负值 for combs in combs_i: combstr = ' '.join(sorted(combs)) if combstr not in lines1234[ix][tm]: # 每种组合初始化 lines1234[ix][tm][combstr] = [ MPTime('0:00.0'), 0 ] lines1234[ix][tm][combstr][0] += line5_tm[L][0] lines1234[ix][tm][combstr][1] += line5_tm[L][1] for ix in range(4): for tm in lines1234[ix]: lines_sorted = {} for k in sorted(lines1234[ix][tm], key=lines1234[ix][tm].__getitem__, reverse=True): # 字典按值排序 lines_sorted[k] = lines1234[ix][tm][k] lines_all[ix][i][ss][tm] = lines_sorted for ix in range(4): writeToPickle( 'D:/sunyiwu/stat/data/Lineups/anaSeason%dLineups.pickle' % (ix + 1), lines_all[ix]) # for combs in lines_all[ix][0]['2019_2020']['LAL']: # print(combs, lines_all[ix][0]['2019_2020']['LAL'][combs]) if __name__ == '__main__': lines5 = LoadPickle('./data/Lineups/anaSeason5Lineups.pickle') splitLineups(lines5)