Anonim_

Untitled

Sep 18th, 2021
735
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import pandas as pd
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. from mplsoccer import VerticalPitch
  5. import seaborn as sns
  6. from mplsoccer import FontManager
  7.  
  8. pd.set_option('display.max_columns', None)
  9.  
  10. # Читаем CSV
  11. df = pd.read_csv('result.csv')
  12.  
  13. # Переводим все координаты для отображения
  14. df['x'] = df['x']*1.2
  15. df['y'] = df['y']*.8
  16. df['endX'] = df['endX']*1.2
  17. df['endY'] = df['endY']*.8
  18.  
  19. # Откидываем ненужные столбцы
  20. df = df[['teamId', 'playerId', 'minute', 'second', 'x', 'y','endX', 'endY', 'type/displayName', 'outcomeType/displayName', 'isShot']]
  21.  
  22. # Выбираем только действия нужной команды
  23. df = df[df['teamId'] == 63].reset_index()  
  24.  
  25. # Подсчитываем время каждого действия
  26. df['time'] = df['minute'] * 60 + df['second']
  27.  
  28. # Оставляем из всех событий только успешные передачи и удары
  29. shots = df[df['isShot'] == True]
  30. passes = df[(df['type/displayName'] == 'Pass') & (df['outcomeType/displayName'] == 'Successful')]
  31. events = pd.concat([shots, passes], axis=0).reset_index()
  32.  
  33. print(events)
  34.  
  35. # Формируем DataFrame, где строки — зоны, а столбцы — их границы и искомое значение
  36. zones = pd.DataFrame(columns=['x1', 'x2', 'y1', 'y2', 'result'])
  37.  
  38. # Начинаем заполнять зоны
  39. for i in range(6):
  40.     for j in range(5):
  41.         # Считаем координаты зоны
  42.         x1 = i * 20
  43.         x2 = (i + 1) * 20
  44.         y1 = j * 16
  45.         y2 = (j + 1) * 16
  46.  
  47.         # Записываем в наш датафрейм
  48.         zones = zones.append({
  49.             'x1': x1,
  50.             'x2': x2,
  51.             'y1' : y1,
  52.             'y2' : y2,
  53.             'result' :0
  54.             }, ignore_index=True
  55.         )  
  56.  
  57. print(zones)
  58.  
  59. # Начинаем перебирать зоны
  60. for i in range(30):
  61.     print(f'Zone #{i}')
  62.    
  63.     # Получаем назад координаты
  64.     x1, x2, y1, y2 = list(zones.iloc[i])[:4]
  65.  
  66.     # Получаем все события именно этой зоны (фильтруем по полученным координатам)
  67.     zone_passes = passes[(x1 <= passes['endX']) & (passes['endX'] <= x2) &
  68.                          (y1 <= passes['endY']) & (passes['endY'] <= y2)]
  69.     zone_shots = shots[(x1 <= shots['x']) & (shots['x'] <= x2) &
  70.                        (y1 <= shots['y']) & (shots['y'] <= y2)]
  71.  
  72.     # Складываем удары и передачи
  73.     zone_events = pd.concat([zone_shots, zone_passes], axis=0)
  74.  
  75.     # Важно: сортируем события в хронологическом порядке
  76.     zone_events = zone_events.sort_values(['time']).reset_index(drop=True)
  77.  
  78.     # Ставим счётчики
  79.  
  80.     # Последняя передача (-1 значит, что передачи ещё не было)
  81.     last_pass_time = -1
  82.  
  83.     # Общее количество передач
  84.     passes_count = 0
  85.  
  86.     # Количество «хороших передач», то есть тех, что привели к удару в течение 10 секунд
  87.     good_passes_count = 0
  88.  
  89.     # Теперь перебираем события
  90.     for j in range(len(zone_events)):
  91.         # Сразу получаем тип события (удар или передача) и время, когда это случилось
  92.         # (просто потому что с короткими названиями переменных проще работать)
  93.         etype = zone_events['type/displayName'][j]
  94.         isshot = zone_events['isShot'][j]
  95.         etime = zone_events['time'][j]
  96.  
  97.         # Если это передача:
  98.         if etype == 'Pass':
  99.             # Увеличиваем количество передач
  100.             passes_count += 1
  101.             # Записываем эту передачу как последнюю
  102.             last_pass_time = etime
  103.         # Если это удар:
  104.         elif isshot:
  105.             # Смотрим, была ли перед ударом передача, и если да, то смотрим, прошло ли меньше 10 секунд
  106.             if last_pass_time != -1 and etime - last_pass_time <= 10:
  107.                 # Если да, то та передача была хорошей — и мы увеличиваем количество хороших передач
  108.                 good_passes_count += 1
  109.                 # И забываем про неё (потому что по условию одна передача не может привести к двум ударам)
  110.                 last_pass_time = -1
  111.  
  112.     # Если не было ни одной передачи, записываем NaN (иначе словим ошибку деления на ноль)
  113.     if passes_count == 0:
  114.         zones['result'][i] = np.nan
  115.     # Иначе записываем отношение хороших передач к общему количеству
  116.     else:
  117.         zones['result'][i] = good_passes_count / passes_count
  118.  
  119.     print()
  120.  
  121. # Результат
  122. print(zones)
RAW Paste Data