We tried to keep our code as user-friendly as possible. As an example on how to use it and and understand the data, we wrote a jupyter notebook sample_analysis.iypnb
.
All the more complex functions are in the utils.py
file.
We recommend using PyCharm or VS Code to work with the code.
We also assume that you have some version of Python installed. We developed using Python 3.10, but other versions should work as well.
python -m venv venv
in the terminal.\venv\Scripts\activate
in the terminalsource ./venv/bin/activate
in the terminal (we think, not actually tested)deactivate
in the terminal)pip install -r requirements.txt
in the terminal.There are two ways to load data.
Download event-data from kinexon. In the process, select all columns you want to analyse. This data will have the following format:
"Timestamp (ms)";"Timestamp in local format";"Player ID";Name;"Event type"
;;;;"Changes of Direction";"Magnitude (°)";"Skating Deceleration (Max.) (m/s²)";"Skating Acceleration (Max.) (m/s²)";"Direction (left/right)"
;;;;"Down on Pads";"Impact (g)";"Time (ms)"
;;;;Hits;"Magnitude (g)";"Speed (km/h)"
;;;;"Hockey Exertions";"Duration (s)";"Hockey Load / min";"Hockey Load (max.)";"Distance (m)";"Speed (max.) (km/h)";"Hockey Exertion"
;;;;Shifts;"Duration (s)";Distance;"Distance (speed | Very low)";"Distance (speed | Low)";"Distance (speed | Medium)";"Distance (speed | High)";"Distance (speed | Very high)";"Distance (speed | Sprint)";"Distance (speed | 0 - 0 km/h)";"Metabolic Power (Ø)";"Speed (max.)";"Skating Load";"Skating Intensity"
;;;;"Skating Accelerations";"Duration (s)";"Distance (m)";"Speed (max.) (km/h)";"Skating Acceleration (Max.) (m/s²)";"Skating Acceleration (Ø) (m/s²)";"Speed Change (km/h)";"Acceleration Category"
;;;;"Skating Bursts";"Duration (s)";"Distance (m)";"Speed (max.)";"Skating Acceleration (Max.) (m/s²)";"Skating Bursts"
;;;;"Skating Decelerations";"Duration (s)";"Distance (m)";"Speed (max.) (km/h)";"Skating Deceleration (Max.) (m/s²)";"Skating Deceleration (Ø) (m/s²)";"Speed Change (km/h)";"Deceleration Category"
;;;;"Skating Transitions";"Body Rotation (°)";"Previous Speed (km/h)";"Following Speed (km/h)";"Direction (left/right)"
;;;;Sprints;"Duration (s)";"Distance (m)";"Speed (max.) (km/h)";"Speed (Ø) (km/h)";"Sprint category"
;;;;Turns;"Duration (s)";"Radius (m)";"Angle (°)";"Direction (left/right)";"End Speed (km/h)";"Start Speed (km/h)";"Turn category"
[... actual data ...]
Our function utils.read_file(file_name, event_type)
will import this CSV file and return a dataframe.
In our case, event_type
is “Shifts”. The function will dismiss all other lines starting with ;;;;
and read the correct columns for the chosen event type.
Alternatively, the CSV file can be edited manually to have following format:
"Timestamp (ms)";"Timestamp in local format";"Player ID";Name;"Event type";"Duration (s)";Distance;"Distance (speed | Very low)";"Distance (speed | Low)";"Distance (speed | Medium)";"Distance (speed | High)";"Distance (speed | Very high)";"Distance (speed | Sprint)";"Distance (speed | 0 - 0 km/h)";"Metabolic Power (Ø)";"Speed (max.)";"Skating Load";"Skating Intensity"
This enables you to read the data with a simple pandas.read_csv(file_name)
.
Create a JSON file with following content. Then use utils.read_file_web()
, supplying the path to the file, to download the data as dataframe.
{
"API_KEY" : "insert_some_api_key",
"USER" : "insert_username_to_access_page",
"PASSWORD" : "insert_passwort_to_accesss_page"
}
Hint: Does not yet work very well.
To create shifts and plot them, use utils.plot_shifts_with_intensity()
.
This function requires the dataframe to plot and a block_config. The block_config is an algorithm configuration, which specifies how to search for shifts, whether you want verbose information, a team name, file name for labelling the plot and an option to save the plots to PNG.
To simplify the creation of the block_config, we provide a function utils.generate_block_config()
.
See the sample_analysis.ipynb
for an example on how to use these functions.
To analyze skating intensity and visualize the results for specific players, use utils.plot_skating_intensity()
.
This function requires a preprocessed DataFrame and parameters for player selection and the time window of interest. The DataFrame should include columns for 'Timestamp (ms)', 'Name', 'Skating Intensity', 'End Timestamp', and 'Readable Timestamp'
.
Quick Setup
utils.read_file(FILE, EVENT_TYPE)
to load player shift events from a CSV file.utils.add_sis_column(df)
.utils.plot_skating_intensity(df_with_sis, selected_players, start_time, end_time)
to visualize skating intensity over time, excluding goalkeepers.For a step-by-step guide and examples on how to use these functions, refer to sample_analysis.ipynb
.
The Shift Intensity Score (SIS) is a pivotal metric derived from skating intensity data, providing insights into a player’s performance by comparing their shift intensity with the team’s average. Below is the methodology for calculating SIS and its implications for performance analysis.
Average Shift Intensity: Calculate the average intensity for each player’s shift by summing up the intensity values during a shift and dividing by the number of measurements within that shift.
Average Player Intensity: Determine the average intensity across all shifts for each player by summing the average intensities of all shifts for a player and dividing by the total number of shifts.
Overall Average Shift Intensity: Calculate the team-wide average intensity by summing the average shift intensities of all players and dividing by the total number of shifts across all players.
Shift Intensity Score (SIS): Finally, determine the SIS for each player by dividing their average player intensity by the overall average shift intensity.
Leveraging SIS allows coaches and trainers to make informed decisions to enhance team strategy and player development.