Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import pandas as pd
- import numpy as np
- import matplotlib.pyplot as plt
- from mplsoccer import VerticalPitch
- import seaborn as sns
- from mplsoccer import FontManager
- pd.set_option('display.max_columns', None)
- # Читаем CSV
- df = pd.read_csv('result.csv')
- # Переводим все координаты для отображения
- df['x'] = df['x']*1.2
- df['y'] = df['y']*.8
- df['endX'] = df['endX']*1.2
- df['endY'] = df['endY']*.8
- # Откидываем ненужные столбцы
- df = df[['teamId', 'playerId', 'minute', 'second', 'x', 'y','endX', 'endY', 'type/displayName', 'outcomeType/displayName', 'isShot']]
- # Выбираем только действия нужной команды
- df = df[df['teamId'] == 63].reset_index()
- # Подсчитываем время каждого действия
- df['time'] = df['minute'] * 60 + df['second']
- # Оставляем из всех событий только успешные передачи и удары
- shots = df[df['isShot'] == True]
- passes = df[(df['type/displayName'] == 'Pass') & (df['outcomeType/displayName'] == 'Successful')]
- events = pd.concat([shots, passes], axis=0).reset_index()
- print(events)
- # Формируем DataFrame, где строки — зоны, а столбцы — их границы и искомое значение
- zones = pd.DataFrame(columns=['x1', 'x2', 'y1', 'y2', 'result'])
- # Начинаем заполнять зоны
- for i in range(6):
- for j in range(5):
- # Считаем координаты зоны
- x1 = i * 20
- x2 = (i + 1) * 20
- y1 = j * 16
- y2 = (j + 1) * 16
- # Записываем в наш датафрейм
- zones = zones.append({
- 'x1': x1,
- 'x2': x2,
- 'y1' : y1,
- 'y2' : y2,
- 'result' :0
- }, ignore_index=True
- )
- print(zones)
- # Начинаем перебирать зоны
- for i in range(30):
- print(f'Zone #{i}')
- # Получаем назад координаты
- x1, x2, y1, y2 = list(zones.iloc[i])[:4]
- # Получаем все события именно этой зоны (фильтруем по полученным координатам)
- zone_passes = passes[(x1 <= passes['endX']) & (passes['endX'] <= x2) &
- (y1 <= passes['endY']) & (passes['endY'] <= y2)]
- zone_shots = shots[(x1 <= shots['x']) & (shots['x'] <= x2) &
- (y1 <= shots['y']) & (shots['y'] <= y2)]
- # Складываем удары и передачи
- zone_events = pd.concat([zone_shots, zone_passes], axis=0)
- # Важно: сортируем события в хронологическом порядке
- zone_events = zone_events.sort_values(['time']).reset_index(drop=True)
- # Ставим счётчики
- # Последняя передача (-1 значит, что передачи ещё не было)
- last_pass_time = -1
- # Общее количество передач
- passes_count = 0
- # Количество «хороших передач», то есть тех, что привели к удару в течение 10 секунд
- good_passes_count = 0
- # Теперь перебираем события
- for j in range(len(zone_events)):
- # Сразу получаем тип события (удар или передача) и время, когда это случилось
- # (просто потому что с короткими названиями переменных проще работать)
- etype = zone_events['type/displayName'][j]
- isshot = zone_events['isShot'][j]
- etime = zone_events['time'][j]
- # Если это передача:
- if etype == 'Pass':
- # Увеличиваем количество передач
- passes_count += 1
- # Записываем эту передачу как последнюю
- last_pass_time = etime
- # Если это удар:
- elif isshot:
- # Смотрим, была ли перед ударом передача, и если да, то смотрим, прошло ли меньше 10 секунд
- if last_pass_time != -1 and etime - last_pass_time <= 10:
- # Если да, то та передача была хорошей — и мы увеличиваем количество хороших передач
- good_passes_count += 1
- # И забываем про неё (потому что по условию одна передача не может привести к двум ударам)
- last_pass_time = -1
- # Если не было ни одной передачи, записываем NaN (иначе словим ошибку деления на ноль)
- if passes_count == 0:
- zones['result'][i] = np.nan
- # Иначе записываем отношение хороших передач к общему количеству
- else:
- zones['result'][i] = good_passes_count / passes_count
- print()
- # Результат
- print(zones)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement