Spaces:
Running on Zero
Running on Zero
File size: 6,368 Bytes
1f62eb2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | # Game sequence level microdata processing
import os
import pandas as pd
import numpy as np
import glob
from datetime import datetime
#import seaborn as sns
# get available processor count
import multiprocessing as mp
num_worker = int(mp.cpu_count()/5*4)
from joblib import Parallel, delayed
def process_sequence(iter_game, df):
'''
Generates dataframe of sequence
'''
# For each game, process each data
# For each game of the dataframe
df_iter = df[df.gameIdx == iter_game]
# Files to be saved
df_agent = []
# Pull faceoffs
list_faceoff = df_iter.query(
'eventTypeId == "FACEOFF"'
)
# Create offense-based metrics
# Home team is marked wtih the event code
idx_home = df_iter.eventCode.iloc[0][0:3]
# Away team code get
teamcode = [iter_game[0:3], iter_game[4:7]] # Get teh list of team names
[idx_away] = [iter for iter in teamcode if iter != idx_home]
# Incorrect way
#idx_home = iter_game[0:3]
#idx_away = iter_game[4:7]
# For each faceoff
for iter_faceoff, idx_faceoff in enumerate(list_faceoff.index):
# Get index of the following faceoff
try:
idx_faceoff_next = list_faceoff.index[iter_faceoff + 1]
idx_faceoff_sequence = np.arange(idx_faceoff, idx_faceoff_next)
except: # If the last faceoff of the game, go all the way to the last entry
idx_faceoff_sequence = np.arange(idx_faceoff, df_iter.index.max())
# --------------------------------------------------------------------------------------------------------
# Get the measurements
# Selecting the series based on the faceoff
iter_decision = df.loc[(df.gameIdx == iter_game) & (df.index.isin(idx_faceoff_sequence)), :]
# Series settings
agent_period = iter_decision.period.iloc[0] # Period number
# Time - series lengh
agent_serieslength = np.max(iter_decision.periodTime) - np.min(iter_decision.periodTime)
# Zone start location
# python returns as list
[agent_zonestartloc] = iter_decision[iter_decision.event == 'Faceoff'].rinkSide_play_relative
# Create elemnts
# Based on the home team
# Faceoff win: 1 if home team won, 0 if visiting team won
agent_faceoff = 1 if iter_decision.iloc[0].team_staff == 'home' else 0
# Home-agent type when faceoff: defense or offense
# 1 if opponent (defense) 0 ()
agent_faceoff_posture = 'offense' if iter_decision.iloc[0].rinkSide_play_relative == 'opponent' else 'defense'
# How many zones used for the action
# If more than one, it means that the zone exit happened
# 0 if only one zone, 1 otherwise (zone changed)
agent_zonestay = 0 if len(np.unique(iter_decision[iter_decision.eventTypeId != 'STOP'].rinkSide_play)) == 1 else 1
# Sequence where goal happened
agent_goal = 0
# 1 if goal exist, 0 otherwise
# Sequence where goal made by home (1) or away (-1) or no goal exist
# Tracking goal information
agent_goal_type = "none"
agent_goal_fin = 0
# non-even goal (6-5 with goalie pulled)
# powerplay goal or Empty net goal (maybe its coded out)
# strength_name: [nan, 'Even', 'Power Play', 'Short Handed']
if ("GOAL" in list(iter_decision.eventTypeId)): # If a goal happened in the sequence
# Identify event record of goal: There should be one only
iter_goalseries = iter_decision.loc[iter_decision.eventTypeId == 'GOAL', :]
# (_) Get information on who made the goal
if (iter_goalseries['team_staff'].iloc[0] == 'home'):
agent_goal = 1
else:
agent_goal = -1
# (_) Get the goal type
agent_goal_type = iter_goalseries['strength_name'].iloc[0]
# (_) Information if the goal is game-winning
agent_goal_fin = 1 if (iter_goalseries['gameWinningGoal'].iloc[0] == True) else 0
else: #no action needed
None
## Team - offense perspective
# Team identity of the offense
# Default is NEUT given they are starting at neutral location
agent_offense_id = "NEUT"
if (agent_zonestartloc == "own"):
agent_offense_id = idx_away
elif (agent_zonestartloc == "opponent"):
agent_offense_id = idx_home
# Has offense won the faceoff, default is 0 (i.e. neurtral zone start)
agent_offense_faceoff_won = 0
if agent_offense_id == idx_home:
if agent_faceoff == 1:
agent_offense_faceoff_won = 1
else:
None
else: #(df_agent.idx_offense[iter] == df_agent.idx_away[iter]):
# Else if the away team is the offensive zone team
if agent_faceoff == 0:
agent_offense_faceoff_won = 1
else:
None
# SOmething to go along with the possession duration:
# Shot count for the period (subtract the cumulative count)
# --------------------------------------------------------------------------------------------------------
# Create dataframe to save
tempdf_agent = pd.DataFrame(
data = {
'gameIdx':iter_decision.gameIdx.iloc[0],
'team_home' : idx_home,
'team_opponent' : idx_away,
'period': agent_period,
'time_length': agent_serieslength,
'zone_faceoff_home': agent_zonestartloc,
'zone_faceoff_offense':agent_offense_id,
'faceoff_won_home': agent_faceoff,
'faceoff_won_offense':agent_offense_faceoff_won,
'posture': agent_faceoff_posture,
'zone_change': agent_zonestay,
'goal': agent_goal,
'goal_strengh':agent_goal_type,
'goal_finalwin':agent_goal_fin
}, index = [idx_faceoff]
)
# Save the agent work
if len(df_agent) == 0: # The first element
df_agent = tempdf_agent
else: # append the existing
df_agent = pd.concat([df_agent, tempdf_agent])
return df_agent |