Сводные таблицы с футболистами

Исходные данные представлены в виде плоской таблицы:

import pandas as pd

url = 'https://raw.githubusercontent.com/dm-fedorov/pandas_basic/master/data/football.csv'

df = pd.read_csv(url)
df.head()
Unnamed: 0 Name Age Nationality Club Value Wage Position Crossing Finishing ... Penalties Composure Marking StandingTackle SlidingTackle GKDiving GKHandling GKKicking GKPositioning GKReflexes
0 0 L. Messi 31 Argentina FC Barcelona 110500000 565000 RF 84 95 ... 75 96 33 28 26 6 11 15 14 8
1 1 Cristiano Ronaldo 33 Portugal Juventus 77000000 405000 ST 84 94 ... 85 95 28 31 23 7 11 15 14 11
2 2 Neymar Jr 26 Brazil Paris Saint-Germain 118500000 290000 LW 79 87 ... 81 94 27 24 33 9 9 15 15 11
3 3 De Gea 27 Spain Manchester United 72000000 260000 GK 17 13 ... 40 68 15 21 13 90 85 87 88 94
4 4 K. De Bruyne 27 Belgium Manchester City 102000000 355000 RCM 93 82 ... 79 88 68 58 51 15 13 5 10 13

5 rows × 42 columns

Функция pivot_table позволяет быстро и просто составлять сводные таблицы:

df['Club']
0               FC Barcelona
1                   Juventus
2        Paris Saint-Germain
3          Manchester United
4            Manchester City
                ...         
12892        Crewe Alexandra
12893         Trelleborgs FF
12894       Cambridge United
12895        Tranmere Rovers
12896        Tranmere Rovers
Name: Club, Length: 12897, dtype: object
df['Club'].isin(['FC Barcelona',
                 'Real Madrid',
                 'Juventus',
                 'Manchester United'])
0         True
1         True
2        False
3         True
4        False
         ...  
12892    False
12893    False
12894    False
12895    False
12896    False
Name: Club, Length: 12897, dtype: bool
df.query("Club == 'FC Barcelona' or Club == 'Real Madrid'")
Unnamed: 0 Name Age Nationality Club Value Wage Position Crossing Finishing ... Penalties Composure Marking StandingTackle SlidingTackle GKDiving GKHandling GKKicking GKPositioning GKReflexes
0 0 L. Messi 31 Argentina FC Barcelona 110500000 565000 RF 84 95 ... 75 96 33 28 26 6 11 15 14 8
6 6 L. Modrić 32 Croatia Real Madrid 67000000 420000 RCM 86 72 ... 82 84 60 76 73 13 9 7 14 9
7 7 L. Suárez 31 Uruguay FC Barcelona 80000000 455000 RS 77 93 ... 85 85 62 45 38 27 25 31 33 37
8 8 Sergio Ramos 32 Spain Real Madrid 51000000 380000 RCB 66 60 ... 75 82 87 92 91 11 8 9 7 11
11 11 T. Kroos 28 Germany Real Madrid 76500000 355000 LCM 88 76 ... 73 85 72 79 69 10 11 13 7 10
18 18 M. ter Stegen 26 Germany FC Barcelona 58000000 240000 GK 15 14 ... 25 69 25 13 10 87 85 88 85 90
19 19 T. Courtois 26 Belgium Real Madrid 53500000 240000 GK 14 14 ... 27 66 20 18 16 85 91 72 86 88
20 20 Sergio Busquets 29 Spain FC Barcelona 51500000 315000 CDM 62 67 ... 60 90 90 86 80 5 8 13 9 13
27 27 Casemiro 26 Brazil Real Madrid 59500000 285000 CDM 52 59 ... 66 84 88 90 87 13 14 16 12 12
30 30 Isco 26 Spain Real Madrid 73500000 315000 LW 75 79 ... 76 86 60 64 51 10 8 12 15 6
32 32 Coutinho 26 Brazil FC Barcelona 69500000 340000 LW 79 79 ... 70 85 55 54 47 12 7 9 14 6
35 35 Marcelo 30 Brazil Real Madrid 43000000 285000 LB 90 70 ... 59 86 71 85 86 12 5 5 5 9
36 36 G. Bale 28 Wales Real Madrid 60000000 355000 ST 87 86 ... 76 86 54 55 52 15 15 11 5 6
42 42 S. Umtiti 24 France FC Barcelona 57000000 205000 CB 69 51 ... 61 82 90 89 86 15 10 14 12 15
46 46 K. Navas 31 Costa Rica Real Madrid 30500000 195000 GK 11 15 ... 25 67 28 14 14 90 81 75 82 90
49 49 Jordi Alba 29 Spain FC Barcelona 38000000 250000 LB 87 73 ... 59 79 72 84 85 13 15 13 6 13
53 53 I. Rakitić 30 Croatia FC Barcelona 46500000 260000 RCM 84 83 ... 82 81 72 74 70 14 11 12 5 9
54 54 Piqué 31 Spain FC Barcelona 34000000 240000 RCB 57 64 ... 69 86 91 86 84 10 11 14 15 8
62 62 R. Varane 25 France Real Madrid 50000000 210000 RCB 36 40 ... 43 82 87 88 87 11 11 9 5 14
79 79 Marco Asensio 22 Spain Real Madrid 54000000 215000 RW 82 82 ... 62 83 40 42 39 13 9 6 12 10
96 96 A. Vidal 31 Chile FC Barcelona 26000000 205000 CAM 76 75 ... 81 81 82 87 86 4 2 4 2 4
105 105 K. Benzema 30 France Real Madrid 37000000 240000 ST 75 81 ... 82 79 47 15 12 13 11 5 5 7
141 141 O. Dembélé 21 France FC Barcelona 40000000 155000 RW 78 78 ... 75 75 42 30 33 6 6 14 10 13
153 153 Lucas Vázquez 27 Spain Real Madrid 27000000 205000 RW 86 73 ... 56 75 42 50 44 9 16 9 9 7
190 190 Arthur 21 Brazil FC Barcelona 32500000 125000 LCM 70 72 ... 69 84 65 76 70 6 13 13 11 12
195 195 C. Lenglet 23 France FC Barcelona 26000000 135000 LCB 36 23 ... 43 74 85 82 81 10 10 9 12 7
204 204 J. Cillessen 29 Netherlands FC Barcelona 18000000 135000 GK 17 10 ... 21 61 18 12 11 80 83 75 81 80
235 235 Nélson Semedo 24 Portugal FC Barcelona 20000000 125000 RB 74 50 ... 38 75 75 78 79 16 12 10 14 12
239 239 Dani Ceballos 21 Spain Real Madrid 25000000 120000 LCM 74 68 ... 55 80 62 75 74 12 15 16 7 13
291 291 Mariano 24 Dominican Republic Real Madrid 20000000 140000 ST 50 81 ... 75 68 41 40 34 12 14 6 8 15
362 365 Marcos Llorente 23 Spain Real Madrid 16000000 110000 CDM 56 39 ... 53 76 76 79 72 13 6 6 11 15
605 613 T. Vermaelen 32 Belgium FC Barcelona 5000000 110000 CB 63 52 ... 62 72 72 79 80 9 10 7 11 15
1464 1515 Aleñá 20 Spain FC Barcelona 6000000 58000 CM 66 66 ... 73 70 70 62 48 12 9 10 8 12
5135 5293 Fidalgo 21 Spain Real Madrid 875000 20000 CM 61 49 ... 49 68 46 51 47 10 9 10 11 9
5377 5539 Chumi 19 Spain FC Barcelona 1000000 11000 CB 38 30 ... 50 62 70 65 63 7 14 9 11 14
5613 5777 Jorge Cuenca 18 Spain FC Barcelona 850000 11000 CB 40 27 ... 44 57 62 66 63 10 12 5 14 12
5989 6156 Sergio López 19 Spain Real Madrid 875000 9000 RB 63 52 ... 43 62 59 61 62 12 12 11 7 13
6124 6293 Guillem Jaime 19 Spain FC Barcelona 975000 13000 RW 63 54 ... 49 66 52 55 56 9 11 12 10 6
6150 6320 Fran García 18 Spain Real Madrid 550000 9000 LB 65 42 ... 39 60 60 58 59 9 6 12 9 11
6694 6869 Manu Hernando 19 Spain Real Madrid 700000 9000 CB 44 32 ... 42 47 70 65 67 11 12 13 12 5
7312 7493 Ezkieta 21 Spain FC Barcelona 525000 10000 GK 16 12 ... 24 33 13 17 15 65 58 59 59 64
7314 7495 Dani Gómez 19 Spain Real Madrid 800000 12000 ST 32 67 ... 57 44 41 12 15 7 10 13 8 14
8436 8628 L. Zidane 20 France Real Madrid 350000 9000 GK 12 8 ... 19 36 13 11 13 65 60 61 62 61
9028 9226 Iñaki Peña 19 Spain FC Barcelona 450000 4000 GK 10 6 ... 17 38 9 10 11 63 57 64 57 62

44 rows × 42 columns

df['Club'].isin(['FC Barcelona',
                 'Real Madrid',
                 'Juventus',
                 'Manchester United'])
0         True
1         True
2        False
3         True
4        False
         ...  
12892    False
12893    False
12894    False
12895    False
12896    False
Name: Club, Length: 12897, dtype: bool
pivot = df.loc[df['Club'].isin(['FC Barcelona','Real Madrid','Juventus','Manchester United'])].\
                pivot_table(values='Wage',
                            index='Nationality',
                            columns='Club',
                            aggfunc=sum)

pivot
C:\Users\dfedorov\AppData\Local\Temp\ipykernel_3852\736501139.py:2: FutureWarning: The provided callable <built-in function sum> is currently using DataFrameGroupBy.sum. In a future version of pandas, the provided callable will be used directly. To keep current behavior pass the string "sum" instead.
  pivot_table(values='Wage',
Club FC Barcelona Juventus Manchester United Real Madrid
Nationality
Argentina 565000.0 205000.0 206000.0 NaN
Belgium 110000.0 NaN 230000.0 240000.0
Bosnia Herzegovina NaN 180000.0 NaN NaN
Brazil 465000.0 335000.0 91000.0 570000.0
Chile 205000.0 NaN 215000.0 NaN
Costa Rica NaN NaN NaN 195000.0
Croatia 260000.0 160000.0 NaN 420000.0
Dominican Republic NaN NaN NaN 140000.0
Ecuador NaN NaN 120000.0 NaN
England NaN NaN 478000.0 NaN
France 495000.0 145000.0 375000.0 459000.0
Germany 240000.0 160000.0 NaN 355000.0
Italy NaN 460000.0 88000.0 NaN
Ivory Coast NaN NaN 105000.0 NaN
Morocco NaN 160000.0 NaN NaN
Netherlands 135000.0 NaN NaN NaN
Poland NaN 125000.0 NaN NaN
Portugal 125000.0 405000.0 NaN NaN
Scotland NaN NaN 11000.0 NaN
Serbia NaN NaN 165000.0 NaN
Spain 912000.0 NaN 260000.0 1404000.0
Uruguay 455000.0 NaN NaN NaN
Wales NaN NaN 13000.0 355000.0

Для начала разберем конструкцию:

df.loc[df['Club'].isin(['FC Barcelona','Real Madrid','Juventus','Manchester United'])]

Она позволяет отфильтровать датафрейм по колонке Club, где значение в колонке соответствует одному из перечисленных в массиве клубов.

Посмотрим на параметры

pivot_table(values=['Wage'], index=['Nationality'], columns=['Club'], aggfunc='sum')

Для того, чтобы добавить столбец и строку с итоговыми значениями, нужно добавить параметр margins=True:

pivot = df.loc[df['Club'].isin(['FC Barcelona','Real Madrid','Juventus','Manchester United'])].\
                pivot_table(values='Wage',
                            index='Nationality',
                            columns='Club',
                            aggfunc=sum,
                            margins=True)

pivot
C:\Users\dfedorov\AppData\Local\Temp\ipykernel_3852\1600286794.py:2: FutureWarning: The provided callable <built-in function sum> is currently using DataFrameGroupBy.sum. In a future version of pandas, the provided callable will be used directly. To keep current behavior pass the string "sum" instead.
  pivot_table(values='Wage',
C:\Users\dfedorov\AppData\Local\Temp\ipykernel_3852\1600286794.py:2: FutureWarning: The provided callable <built-in function sum> is currently using DataFrameGroupBy.sum. In a future version of pandas, the provided callable will be used directly. To keep current behavior pass the string "sum" instead.
  pivot_table(values='Wage',
C:\Users\dfedorov\AppData\Local\Temp\ipykernel_3852\1600286794.py:2: FutureWarning: The provided callable <built-in function sum> is currently using DataFrameGroupBy.sum. In a future version of pandas, the provided callable will be used directly. To keep current behavior pass the string "sum" instead.
  pivot_table(values='Wage',
Club FC Barcelona Juventus Manchester United Real Madrid All
Nationality
Argentina 565000.0 205000.0 206000.0 NaN 976000
Belgium 110000.0 NaN 230000.0 240000.0 580000
Bosnia Herzegovina NaN 180000.0 NaN NaN 180000
Brazil 465000.0 335000.0 91000.0 570000.0 1461000
Chile 205000.0 NaN 215000.0 NaN 420000
Costa Rica NaN NaN NaN 195000.0 195000
Croatia 260000.0 160000.0 NaN 420000.0 840000
Dominican Republic NaN NaN NaN 140000.0 140000
Ecuador NaN NaN 120000.0 NaN 120000
England NaN NaN 478000.0 NaN 478000
France 495000.0 145000.0 375000.0 459000.0 1474000
Germany 240000.0 160000.0 NaN 355000.0 755000
Italy NaN 460000.0 88000.0 NaN 548000
Ivory Coast NaN NaN 105000.0 NaN 105000
Morocco NaN 160000.0 NaN NaN 160000
Netherlands 135000.0 NaN NaN NaN 135000
Poland NaN 125000.0 NaN NaN 125000
Portugal 125000.0 405000.0 NaN NaN 530000
Scotland NaN NaN 11000.0 NaN 11000
Serbia NaN NaN 165000.0 NaN 165000
Spain 912000.0 NaN 260000.0 1404000.0 2576000
Uruguay 455000.0 NaN NaN NaN 455000
Wales NaN NaN 13000.0 355000.0 368000
All 3967000.0 2335000.0 2357000.0 4138000.0 12797000

Пример решения

Сводная таблица, показывающая максимальные зарплаты игроков на разных позициях, играющих за разные клубы, была создана с помощью кода:

df2 = df.pivot_table(columns='Position', index='Club', values='Wage', aggfunc='max')

С помощью какого кода можно получить из этой таблицы информацию о максимальной зарплате вратаря (GK), играющего за футбольный клуб "Manchester City"?

Обратите внимание, что в датафрейме получилось много NaN (Not a Number). Это означает, что на пересечении строки и столбца нет данных, например, в клубе Juventus нет футболистов из Бельгии:

pivot.loc['Belgium']
Club
FC Barcelona         110000.0
Juventus                  NaN
Manchester United    230000.0
Real Madrid          240000.0
All                  580000.0
Name: Belgium, dtype: float64

Для того, чтобы заменить NaN на 0, можно применить дополнительный параметр fill_value. Этот параметр принимает значение, которым нужно заполнить все NaN в получившейся сводной таблице:

pivot = df.loc[df['Club'].isin(['FC Barcelona','Real Madrid','Juventus','Manchester United'])].\
                pivot_table(values='Wage',
                            index='Nationality',
                            columns='Club',
                            aggfunc=sum,
                            margins=True,
                            fill_value=0)

pivot

Задание 1

Создайте сводную таблицу, содержащую сведения о количестве игроков, занимающих разные позиции в каждом клубе. Отсутствующие значения замените нулями.

Каково среднее количество вратарей (GK) в клубе? Ответ округлите до трёх цифр после запятой.

Задание 2

Используя таблицу, созданную на предыдущем шаге, определите, сколько клубов не содержат данных о центральных полузащитниках (CM).

Подсказка: для выполнения этого задания желательно сохранить сводную таблицу в виде отдельного датафрейма и сгруппировать часть данных этого датафрейма с помощью value_counts().

Задание 3

С помощью сводной таблицы и функции loc посчитайте, сколько получают ("Wage") русские футболисты ("Russia"), играющие за ФК "AS Monaco".