Группировка футболистов (продолжение)

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

Предположим, что перед нами стоит задача посчитать сумму зарплат по клубам, чтобы найти клуб с самой высокой зарплатой.

Мы можем сделать это с помощью функции groupby:

df.groupby('Club')
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x000001F8337F8320>

Мы передали на вход функции groupby колонку (или список колонок), по которой будет осуществляться группировка. Но в ответ получили что-то странное. Это объект группировки, он хранит в себе информацию о том, какие строки датафрейма (по индексным номерам) соответствуют определенной группе (в нашем случае определенному клубу). Увидеть это можно, вызвав у объекта группировки атрибут groups:

df.groupby('Club').groups
{' SSV Jahn Regensburg': [1642, 2284, 2374, 2401, 2575, 2583, 2850, 2868, 3418, 3908, 3989, 4154, 5151, 5177, 5525, 5885, 6070, 6679, 7173, 7477, 8905, 9061, 10825, 12482], '1. FC Heidenheim 1846': [1060, 1805, 1978, 2050, 2066, 2926, 3584, 3605, 4312, 4457, 4783, 6818, 7160, 7166, 7460, 9475, 10052, 10565, 11217, 12236], '1. FC Kaiserslautern': [2931, 3590, 4270, 4413, 4475, 4483, 4709, 4779, 5079, 5325, 5403, 5855, 5917, 7295, 8784, 9496, 9964, 10019, 10122, 10671, 11500, 11970, 12222], '1. FC Köln': [166, 379, 899, 1399, 3415, 6904, 7052, 8892, 12171, 12376], '1. FC Magdeburg': [1967, 2069, 2152, 2569, 2886, 3030, 3300, 3332, 4436, 4913, 5002, 5033, 5493, 5768, 6329, 7046, 7595, 8387, 9626, 11125, 11400], '1. FC Nürnberg': [724, 1208, 1254, 1920, 4775, 5265, 5556, 5985, 8590, 8632, 9217, 9858, 10480], '1. FC Union Berlin': [1422, 1493, 2530, 2876, 3635, 3844, 4683, 4826, 11038, 11296, 12340], '1. FSV Mainz 05': [545, 670, 765, 1201, 1342, 6218, 6868, 8792, 10293, 10561, 10566], 'AC Ajaccio': [1507, 1672, 2118, 2180, 2798, 3046, 3742, 3879, 4522, 4697, 5698, 6607, 7484, 8519, 9449, 11043, 11789, 12221, 12244], 'AC Horsens': [2491, 2924, 3640, 3881, 5419, 5471, 5929, 6518, 6669, 6736, 7115, 8049, 8203, 8237, 9281, 9804, 10251, 10454, 11241, 11513, 11763, 12011, 12598, 12692, 12743], 'AD Alcorcón': [1407, 1607, 1651, 2117, 2216, 2619, 3011, 3177, 3278, 3601, 3801, 4808, 6385, 6805, 7120, 7141, 7397, 8901, 9526], 'ADO Den Haag': [1377, 1825, 2976, 3037, 3611, 3783, 3825, 4555, 4969, 5599, 6344, 6787, 6816, 8296, 8391, 9055, 9157, 10330, 10506], 'AEK Athens': [700, 751, 754, 1180, 1309, 1356, 3314, 5304, 5975, 10026, 12119], 'AFC Wimbledon': [3464, 3868, 4990, 5292, 5566, 6228, 6526, 6566, 7070, 7181, 7241, 7256, 7698, 7978, 8213, 8356, 9521, 10693, 11132, 11318, 12078, 12139, 12142, 12239, 12266, 12679], 'AIK': [1451, 1961, 3323, 3466, 3651, 4274, 4615, 5201, 6418, 7655, 8072, 8611, 9363, 11325, 11341, 11399, 11633, 11729, 12386], 'AJ Auxerre': [1606, 2028, 2132, 2962, 3597, 4731, 4980, 5006, 5396, 5542, 5626, 8419, 9728, 10420, 10471, 10849, 11520], 'AS Béziers': [1557, 4215, 4796, 5134, 5604, 5809, 5965, 6427, 6435, 6558, 6867, 7590, 7730, 7870, 8428, 8540, 8587, 9981, 10106, 10771, 10907, 10987, 11444, 11689, 11942], 'AS Monaco': [137, 172, 173, 298, 365, 400, 428, 475, 477, 918, 991, 4009, 4487, 6278, 6431, 7588, 8046, 8314], 'AS Nancy Lorraine': [1995, 2169, 2428, 2432, 2943, 3209, 3237, 3289, 3457, 3579, 3920, 4465, 5026, 5666, 5972, 6374, 6963, 7856, 8468, 9543, 10306, 10854, 11260, 11746, 11906], 'AS Saint-Étienne': [136, 725, 822, 897, 1314, 1394, 1913, 2643, 2702, 6892, 8321, 9822, 10234, 10718, 11503], 'AZ Alkmaar': [849, 1158, 1246, 1768, 3458, 3891, 4207, 4842, 6039, 7059], 'Aalborg BK': [1458, 2509, 2646, 3862, 3922, 5707, 6119, 6555, 6715, 7094, 7961, 9259, 9334, 10694, 11262, 11816, 12342, 12440, 12510, 12520, 12652, 12758], 'Aarhus GF': [2318, 2610, 2936, 3490, 4530, 4546, 4855, 4886, 4920, 4941, 5161, 6213, 6575, 7096, 7768, 8082, 9731, 11769, 12301, 12570, 12574, 12580, 12634, 12663, 12700], 'Aberdeen': [2444, 2978, 3317, 3574, 4026, 4144, 4280, 4824, 4949, 5524, 7444, 9203, 9943, 11232, 12248, 12425, 12675, 12765], 'Accrington Stanley': [2227, 2600, 3827, 4031, 4295, 5336, 5675, 6433, 6493, 6554, 7891, 8074, 8508, 8518, 8928, 9515, 9782, 9940, 10059, 10141, 10349, 10424, 10474, 10928, 11020, 12346, 12422, 12456], 'Adelaide United': [1533, 2387, 2460, 3354, 3942, 4130, 4451, 4668, 6908, 7090, 7252, 7706, 8316, 9212, 9623, 9980, 10220, 10458, 12055, 12409, 12485, 12613, 12628, 12703], 'Ajax': [152, 188, 234, 300, 319, 352, 737, 1335, 3111, 3769, 4847, 4897, 5010], 'Akhisar Belediyespor': [722, 796, 1781, 2049, 2096, 2594, 2617, 2699, 4929, 5376, 5589, 6870, 7081, 8801], 'Al Ahli': [419, 524, 1617, 1815, 2256, 2519, 2521, 3614, 4048, 6163, 6794, 9114, 9636, 9922, 11292, 11330, 11380, 11724, 11728, 11730, 11839, 12230], 'Al Batin': [1540, 1959, 2525, 3812, 4591, 4771, 7178, 7220, 8091, 8146, 8288, 9275, 9606, 10196, 10688, 11035, 11042, 11170, 11659, 12106, 12135, 12198, 12324, 12392, 12427, 12749, 12787, 12788], 'Al Faisaly': [2021, 2514, 2522, 2644, 2693, 3217, 4859, 4867, 5059, 5715, 6144, 6347, 7322, 7855, 8061, 9207, 9329, 10389, 10880, 10944, 11011, 11012, 11172, 11403, 11554, 11696, 11739], 'Al Fateh': [1374, 2376, 3437, 4198, 4877, 5186, 6452, 6534, 6665, 6907, 7471, 7840, 8279, 8652, 8874, 9086, 9819, 9960, 10312, 11252, 11519, 12064, 12066, 12366, 12371, 12568, 12676], 'Al Fayha': [1252, 1760, 1822, 1850, 3191, 4563, 4919, 5253, 6574, 6775, 6953, 7091, 7196, 7568, 7642, 7798, 8129, 8771, 10323, 10887, 11245, 11312, 11446, 11693, 11933], 'Al Hazem': [2396, 3045, 3627, 4174, 6016, 6931, 7118, 7615, 8711, 8846, 8864, 8869, 8959, 9105, 9262, 9437, 9448, 9793, 10079, 10580, 10927, 11019, 11321, 11597, 11632, 11745, 12058], 'Al Hilal': [281, 505, 653, 1061, 1269, 1316, 1479, 1778, 1915, 2758, 3234, 4180, 4489, 4658, 5409, 7735, 9081, 9436, 9451, 10328, 11340, 11475], 'Al Ittihad': [682, 2358, 2369, 2445, 2707, 2782, 2884, 3831, 4338, 5219, 6299, 6379, 6620, 7436, 7783, 7877, 9517, 10412, 10469, 10486, 10885, 11919], 'Al Nassr': [177, 469, 948, 1067, 1800, 1818, 2334, 2981, 3839, 3850, 4047, 6387, 6998, 7276, 7511, 9979, 10414, 10423, 11299, 11761, 12180, 12544, 12713], 'Al Qadisiyah': [2972, 3493, 3894, 4586, 5327, 5492, 5601, 5817, 5829, 5880, 6598, 7095, 7438, 7527, 7774, 8917, 10110, 11088, 11207, 11324, 11331, 11334, 11416, 11741, 11762, 12004], 'Al Raed': [2157, 2224, 4152, 5195, 5511, 6685, 8040, 8174, 8224, 8310, 8591, 8610, 8744, 9087, 9353, 9488, 9846, 10378, 10593, 11191, 12025, 12159, 12418, 12420, 12807], 'Al Shabab': [1898, 2464, 3138, 4181, 4307, 6207, 6285, 6399, 6434, 7751, 8292, 8443, 8900, 9511, 9575, 9985, 10475, 10600, 10803, 11578, 11714, 11784, 11785, 12584], 'Al Taawoun': [975, 3703, 3724, 5197, 5418, 5792, 6366, 6744, 6789, 6888, 7992, 8140, 8877, 9268, 9430, 9643, 9894, 10018, 10938, 11136, 12343, 12367, 12512, 12525, 12770], 'Al Wehda': [857, 1115, 1211, 1402, 1931, 4235, 4935, 5359, 6103, 7060, 7394, 7620, 8887, 9073, 9523, 9704, 10130, 10452, 10654, 11242, 11253, 11545, 11758, 11894], 'Alanyaspor': [1196, 1794, 2019, 2119, 2366, 2418, 2765, 3185, 3388, 4542, 5156, 9179, 10845, 11054, 11086, 11353, 11619], 'Albacete BP': [1852, 2133, 2968, 3455, 3566, 3755, 5076, 5830, 6972, 7036, 7078, 7493, 7778, 9163, 9903, 11498, 11504], 'Alianza Petrolera': [2327, 2381, 2395, 2992, 3008, 3139, 3608, 4442, 4623, 4703, 4827, 5163, 5275, 6547, 7162, 7300, 7799, 7965, 8079, 9427, 9552, 10155, 10807, 11156, 11347, 12039], 'Amiens SC': [709, 768, 923, 925, 1088, 1395, 1719, 2925, 2935, 6470, 8244, 8306, 9655, 9664, 10317, 10585, 10735], 'América FC (Minas Gerais)': [908, 2592, 2688, 2739, 2949, 4458, 4891, 5993, 6841], 'América de Cali': [1848, 2651, 3758, 3794, 3871, 3882, 4086, 4706, 4940, 6191, 6549, 6989, 10925, 10990, 11202, 11604, 11734, 11991, 12748], 'Angers SCO': [1218, 1820, 1882, 2048, 2312, 3910, 6468, 7204, 7462, 8679, 9265, 10946], 'Antalyaspor': [782, 788, 1952, 2207, 2309, 2493, 3346, 3359, 3412, 3941, 4204, 6582, 6608, 7434, 7535, 9493, 9888, 10931, 11442], 'Argentinos Juniors': [1391, 1923, 2171, 2952, 3961, 4757, 6281, 7820, 8371, 8722, 8837, 9023, 9321, 9339, 9634, 10192, 10227, 10427, 10661, 12681], 'Arka Gdynia': [1629, 3067, 3318, 4187, 4208, 4373, 4519, 4792, 5298, 6709, 6803, 6873, 7908, 8385, 8685, 8865, 8998, 9151, 9974, 10633, 11181, 11773, 11954, 12052, 12228, 12426], 'Arsenal': [33, 74, 87, 126, 135, 194, 215, 230, 257, 331, 380, 483, 570, 1416, 1603, 1979, 5283, 6398, 6583, 7307, 8747, 9892, 10934], 'Ascoli': [2518, 2573, 2692, 3102, 3324, 3364, 3671, 3930, 4088, 4406, 4712, 4858, 5469, 5786, 6139, 6594, 7461, 7738, 7788, 7829, 9442, 10647, 10818, 11335, 12750], 'Aston Villa': [1108, 1184, 1193, 1639, 1753, 1779, 2837, 5065, 5588, 8838, 10265, 10495, 12006, 12373, 12404], 'Atalanta': [140, 254, 436, 479, 481, 525, 708, 732, 1019, 3004, 6914, 7363, 9585], 'Athletic Club de Bilbao': [197, 229, 323, 337, 384, 569, 664, 973, 1012, 1056, 6872, 8092, 10085], 'Atiker Konyaspor': [886, 1009, 1155, 1348, 1591, 1773, 1795, 1868, 1945, 2114, 2896, 3347, 4184, 5180, 6308, 8663], 'Atlanta United': [1057, 1333, 1613, 1754, 2187, 3305, 3333, 4550, 4632, 5451, 5946, 6732, 7208, 7284, 7874, 7989, 9238, 10784, 11048, 11050, 11463, 12167], 'Atlético Bucaramanga': [1284, 1706, 2165, 2273, 3681, 3732, 3762, 4735, 5457, 5609, 5844, 6384, 6540, 6976, 7217, 7522, 7950, 8616, 10337, 11016, 11022, 11326, 11978, 12189], 'Atlético Huila': [1767, 2342, 4411, 4669, 5560, 5683, 6893, 7635, 7697, 7817, 8117, 8178, 8245, 9729, 10381, 10610, 10700, 10912, 11075, 11840, 12247, 12263, 12330, 12629, 12738], 'Atlético Madrid': [9, 12, 17, 83, 86, 100, 106, 111, 146, 161, 189, 256, 423, 6623, 6654, 6900, 7296, 7404, 7587, 8013, 8985, 9080, 9953, 10371, 10510], 'Atlético Mineiro': [855, 1409, 1935, 2036, 2150, 3371], 'Atlético Nacional': [1535, 3062, 3348, 3787, 5847, 6271, 8708, 11972, 12019, 12718, 12843, 12872], 'Atlético Paranaense': [1129, 1255, 1589, 1604, 2159, 2473, 2534, 3097, 3428, 3958, 5882, 6265, 7035], 'Atlético Tucumán': [1455, 1542, 1646, 1917, 2829, 3174, 3802, 3997, 4677, 5276, 6850, 8320, 9923, 10635, 10673, 10812], 'Audax Italiano': [1788, 2002, 2168, 2443, 3855, 3913, 4007, 4353, 4793, 5168, 5205, 5243, 6100, 6333, 6463, 7205, 8357, 8817, 8881, 9362, 9407, 9984, 10641, 12199, 12667], 'BB Erzurumspor': [1718, 2067, 2687, 4535, 5055, 5674, 6475, 7045, 8510, 8742, 8773, 9671, 10466, 10479, 10751, 11523, 12740], 'BK Häcken': [1955, 2086, 2971, 3153, 3463, 4129, 4481, 4500, 4788, 5573, 5852, 6483, 6937, 7203, 8745, 10049, 11192, 11304, 12009, 12205, 12232, 12478, 12715, 12792], 'BSC Young Boys': [649, 771, 1250, 2357, 2664, 5449, 5767, 6220, 7575, 9221, 9417, 11404, 11876, 12108, 12181], 'Bahia': [1247, 1263, 1623, 2260, 2315, 2404, 2629, 2945, 3955, 4347, 5816, 6322], 'Barnsley': [2897, 3094, 3408, 3518, 4358, 5056, 5062, 6325, 6920, 7265, 7780, 10744, 11512, 11516, 11756, 12007, 12060, 12237, 12388, 12599, 12821], 'Bayer 04 Leverkusen': [128, 181, 251, 255, 258, 270, 285, 373, 674, 683, 1049, 2108, 8768, 10316, 10325], 'Beijing Renhe FC': [332, 543, 3232, 5081, 5176, 5474, 6214, 6763, 7055, 7502, 7882, 8073, 8294, 9120, 9933, 9939, 10906, 11246, 11890, 11944, 12192, 12202, 12255, 12391, 12682, 12684, 12876], 'Beijing Sinobo Guoan FC': [205, 563, 2291, 2695, 3319, 3529, 4315, 5333, 5643, 5942, 6226, 7101, 7228, 8000, 8525, 8578, 9555, 9757, 10766, 11509, 11536, 11704, 12466, 12846], 'Belgrano de Córdoba': [2254, 2550, 2682, 4328, 4375, 4473, 4794, 5380, 5927, 6405, 7379, 7716, 8642, 9352, 9657, 10834, 11701, 11882, 12056], 'Benevento': [1020, 1406, 1441, 1538, 3151, 3166, 3644, 4028, 6560, 7583, 9869, 11790], 'Beşiktaş JK': [108, 260, 441, 516, 536, 537, 720, 740, 753, 850, 5864, 6044, 7333, 7386, 9330, 9696, 10281, 12744], 'Birmingham City': [1908, 2074, 2124, 3691, 3766, 4279, 4888, 5395, 5605, 5699, 7330, 7662, 7873, 8246, 10438, 12099], 'Blackburn Rovers': [1667, 1809, 2217, 2454, 2650, 3522, 4034, 4070, 4125, 4538, 4740, 5019, 7593, 8378, 8422, 10529, 10685, 11727, 11742, 11853, 11966], 'Blackpool': [3536, 3677, 3686, 3987, 4024, 4118, 4639, 6093, 6108, 6171, 6529, 6802, 6993, 7031, 7447, 7947, 7982, 8397, 8730, 9491, 9991, 10531, 11307, 11350, 11596, 12533, 12823, 12867], 'Boavista FC': [1327, 2073, 2694, 3009, 3055, 3106, 3479, 5232, 5360, 5484, 6792, 6880, 11377], 'Boca Juniors': [374, 482, 517, 554, 579, 590, 1002, 1091, 1206, 1803, 8367, 9099, 9787], 'Bohemian FC': [6257, 9723, 10084, 10126, 10545, 10579, 10779, 10903, 11234, 11542, 11813, 11819, 11996, 12082, 12111, 12125, 12204, 12445, 12476, 12501, 12618, 12619, 12734, 12799, 12841], 'Bologna': [588, 607, 627, 721, 1023, 1066, 1285, 1600, 1661, 2666, 9533], 'Bolton Wanderers': [1763, 1782, 1903, 1911, 2570, 2700, 2911, 3042, 3196, 3201, 3213, 3530, 3916, 4448, 4967, 5561, 10404, 10590, 10612, 11928, 12170], 'Borussia Dortmund': [68, 134, 209, 233, 245, 266, 273, 294, 360, 364, 371, 415, 630, 979, 1127, 4748, 6513, 9484, 10443, 10853, 10995], 'Borussia Mönchengladbach': [179, 247, 249, 265, 283, 378, 426, 552, 566, 616, 637, 2142, 7769, 7869, 7902, 8076, 8262, 8431, 9744, 10136], 'Botafogo': [906, 1405, 1430, 1525, 1670, 2350, 2377, 3212, 4213, 4305], 'Bournemouth': [846, 1142, 1256, 8512, 8880, 9292, 9314, 10066, 10163, 10248, 10643, 10915, 10916, 11006], 'Boyacá Chicó FC': [2264, 4437, 5013, 5255, 5739, 6295, 6831, 7016, 7040, 7086, 7549, 8207, 8660, 8733, 9452, 10618, 11046, 11405, 11441, 11465, 11768, 11999, 12002, 12338, 12495, 12588], 'Bradford City': [2205, 3555, 3665, 3981, 4381, 4398, 5740, 5780, 5996, 6022, 6274, 6516, 6590, 7240, 7704, 7760, 8142, 8222, 8665, 9460, 10197, 10957, 10958, 11001, 12029, 12195, 12362], 'Bray Wanderers': [10670, 11060, 11070, 11083, 11106, 11383, 11537, 11651, 11674, 11814, 11826, 12046, 12251, 12402, 12410, 12591, 12668, 12705, 12712, 12753, 12801, 12817, 12871], 'Brentford': [1068, 1114, 3065, 3402, 5028, 6010, 6974, 9006, 9975, 10881, 11171, 11244, 11251, 11305, 11481], 'Brescia': [985, 1596, 2267, 2379, 2425, 3554, 3896, 4145, 4226, 4388, 4399, 4822, 5401, 5555, 5784, 7709, 7717, 8066, 9141, 9236, 9505, 9546, 9658], 'Brighton & Hove Albion': [511, 564, 587, 917, 1165, 1241, 1276, 1475, 2761, 3445, 8594, 8643, 8693, 9196, 10613, 10848, 12081], 'Brisbane Roar': [1641, 1906, 2414, 2478, 2890, 2986, 4885, 5049, 5145, 5759, 6771, 9160, 9328, 9742, 10826, 11561, 11636, 11650, 11990, 12036], 'Bristol City': [1266, 1489, 1720, 1804, 1846, 1933, 2018, 2025, 2336, 4948, 5777, 7474, 7883, 9064, 11267, 12216, 12225, 12579], 'Bristol Rovers': [3128, 4272, 4444, 5103, 5553, 5558, 5734, 5788, 6370, 7083, 8238, 9083, 9106, 9503, 9726, 9904, 9965, 10068, 10165, 10339, 10364, 10447, 10530, 10567, 11987, 12080, 12575], 'Brøndby IF': [1131, 2956, 3020, 3588, 3619, 3662, 4064, 5712, 5905, 6062, 6353, 8940, 9783, 12493, 12543, 12735, 12804], ...}

Это означает, что FC Köln соответствуют следующие строки: 166, 379, 899, 1399, 3415, 6904, 7052, 8892, 12171, 12376.

О чем нам это говорит? Нам — ни о чем, но для алгоритма группировки это важная информация. Он поймет, какие строки брать для включения в группу, когда мы решим применить к этим строкам какую-нибудь агрегирующую функцию, например функцию суммы sum:

grouped_df = df.groupby('Club').sum()
grouped_df
Unnamed: 0 Name Age Nationality Value Wage Position Crossing Finishing HeadingAccuracy ... Penalties Composure Marking StandingTackle SlidingTackle GKDiving GKHandling GKKicking GKPositioning GKReflexes
Club
SSV Jahn Regensburg 129124 P. PentkeS. NachreinerA. NandzikB. SallerA. Ge... 609 GermanyGermanyGermanyGermanyGermanyGermanyGerm... 15195000 90000 GKCBLBRBRDMGKCDMCMLBRAMLMRCBRBLMCBSTLDMCBCBSTC... 1104 944 1283 ... 1042 1332 1205 1146 1088 405 406 368 409 424
1. FC Heidenheim 1846 117834 M. SchnattererN. TheuerkaufM. WittekT. Beerman... 473 GermanyGermanyGermanyGermanyGermanyGermanyGerm... 18290000 76000 LMLBCBLCBRBGKCAMRBRCBRMSTRMSTCBRMCMLMCBGKLB 961 860 955 ... 923 1093 888 952 890 335 317 287 335 306
1. FC Kaiserslautern 167351 T. ThieleJ. LöhmannsröbenH. ZuckA. HainaultJ. ... 544 GermanyGermanyGermanyCanadaGermanyGermanyGerma... 11195000 33000 LSRDMLMLCBRSCDMRBRMRMLBCDMSTCBRBGKCBLWGKLMGKCD... 1106 918 1133 ... 1030 1174 938 989 996 392 373 348 368 356
1. FC Köln 54865 T. HornJ. HectorL. SchaubM. LehmannM. BaderC. ... 225 GermanyGermanyAustriaGermanyGermanyGermanyDenm... 46810000 92000 GKLWBRMCDMRBCMCMCBGKGK 444 357 434 ... 431 515 453 458 452 272 251 276 252 268
1. FC Magdeburg 116731 C. BeckJ. FejzićR. WeilS. SchäferN. HammannR. ... 515 GermanyBosnia HerzegovinaGermanyGermanyGermany... 57525000 84000 RSGKCBLCBCBLCMRMCBCBLSRWRCBGKRMRWLBRCMRMGKSTCF 948 903 1044 ... 938 1057 933 930 892 367 373 354 361 394
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
Zagłębie Sosnowiec 220803 K. WrzesińskiT. NowakM. PerdijićM. HeinlothZ. ... 656 PolandPolandCroatiaGermanySerbiaPolandFranceSl... 6815000 27000 LMCAMGKRBLMCBSTLBCBLCBCAMCDMGKLMRMRDMLBRCBLMLD... 1161 1007 1152 ... 1113 1371 1219 1187 1156 427 391 417 391 413
Çaykur Rizespor 119137 M. ÇağıranS. KoçA. ÇamdalıM. SaymakA. TraoréK.... 557 TurkeyGermanyGermanyNetherlandsSenegalTurkeyTu... 27515000 118000 CDMRMRDMCAMLBRBLBCDMRBGKCDMCBLDMLCBRBGKSTLMGKC... 1110 921 1137 ... 1063 1200 1050 1155 1143 375 394 387 388 389
Örebro SK 224465 O. JanssonN. GerzićK. IgboananikeM. AlmebäckM.... 622 SwedenSwedenNigeriaSwedenNigeriaSwedenSwedenSw... 8465000 36000 GKLCMSTCBRWLCBLWRCMRWRCBRWBLWBLWBSTCBSTCBCMLWL... 1114 974 1149 ... 1066 1393 1112 1045 1008 412 406 386 428 407
Östersunds FK 136103 T. PetterssonJ. HopcuttS. KroonD. WidgrenT. Te... 478 SwedenEnglandSwedenSwedenSwedenSwedenGuineaSwe... 11030000 39000 LCBCFRMLBLCMRCBGKCMCMSTCBLMGKRBCMLBRWCAMLMGK 944 805 856 ... 847 1132 920 842 816 342 357 369 337 363
Śląsk Wrocław 172358 M. RobakP. CelebanR. PichA. PiechM. ChrapekAug... 628 PolandPolandSlovakiaPolandPolandPortugalIranPo... 9170000 50000 LSRCBLMRSLDMCDMRMRBLBRDMLBLCBGKRBCDMCBGKCMSTCD... 1058 1054 1289 ... 1150 1314 1047 1161 1129 408 403 367 394 403

650 rows × 41 columns

# лучше так:
grouped_df = df.groupby('Club').agg("sum")
grouped_df
Unnamed: 0 Name Age Nationality Value Wage Position Crossing Finishing HeadingAccuracy ... Penalties Composure Marking StandingTackle SlidingTackle GKDiving GKHandling GKKicking GKPositioning GKReflexes
Club
SSV Jahn Regensburg 129124 P. PentkeS. NachreinerA. NandzikB. SallerA. Ge... 609 GermanyGermanyGermanyGermanyGermanyGermanyGerm... 15195000 90000 GKCBLBRBRDMGKCDMCMLBRAMLMRCBRBLMCBSTLDMCBCBSTC... 1104 944 1283 ... 1042 1332 1205 1146 1088 405 406 368 409 424
1. FC Heidenheim 1846 117834 M. SchnattererN. TheuerkaufM. WittekT. Beerman... 473 GermanyGermanyGermanyGermanyGermanyGermanyGerm... 18290000 76000 LMLBCBLCBRBGKCAMRBRCBRMSTRMSTCBRMCMLMCBGKLB 961 860 955 ... 923 1093 888 952 890 335 317 287 335 306
1. FC Kaiserslautern 167351 T. ThieleJ. LöhmannsröbenH. ZuckA. HainaultJ. ... 544 GermanyGermanyGermanyCanadaGermanyGermanyGerma... 11195000 33000 LSRDMLMLCBRSCDMRBRMRMLBCDMSTCBRBGKCBLWGKLMGKCD... 1106 918 1133 ... 1030 1174 938 989 996 392 373 348 368 356
1. FC Köln 54865 T. HornJ. HectorL. SchaubM. LehmannM. BaderC. ... 225 GermanyGermanyAustriaGermanyGermanyGermanyDenm... 46810000 92000 GKLWBRMCDMRBCMCMCBGKGK 444 357 434 ... 431 515 453 458 452 272 251 276 252 268
1. FC Magdeburg 116731 C. BeckJ. FejzićR. WeilS. SchäferN. HammannR. ... 515 GermanyBosnia HerzegovinaGermanyGermanyGermany... 57525000 84000 RSGKCBLCBCBLCMRMCBCBLSRWRCBGKRMRWLBRCMRMGKSTCF 948 903 1044 ... 938 1057 933 930 892 367 373 354 361 394
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
Zagłębie Sosnowiec 220803 K. WrzesińskiT. NowakM. PerdijićM. HeinlothZ. ... 656 PolandPolandCroatiaGermanySerbiaPolandFranceSl... 6815000 27000 LMCAMGKRBLMCBSTLBCBLCBCAMCDMGKLMRMRDMLBRCBLMLD... 1161 1007 1152 ... 1113 1371 1219 1187 1156 427 391 417 391 413
Çaykur Rizespor 119137 M. ÇağıranS. KoçA. ÇamdalıM. SaymakA. TraoréK.... 557 TurkeyGermanyGermanyNetherlandsSenegalTurkeyTu... 27515000 118000 CDMRMRDMCAMLBRBLBCDMRBGKCDMCBLDMLCBRBGKSTLMGKC... 1110 921 1137 ... 1063 1200 1050 1155 1143 375 394 387 388 389
Örebro SK 224465 O. JanssonN. GerzićK. IgboananikeM. AlmebäckM.... 622 SwedenSwedenNigeriaSwedenNigeriaSwedenSwedenSw... 8465000 36000 GKLCMSTCBRWLCBLWRCMRWRCBRWBLWBLWBSTCBSTCBCMLWL... 1114 974 1149 ... 1066 1393 1112 1045 1008 412 406 386 428 407
Östersunds FK 136103 T. PetterssonJ. HopcuttS. KroonD. WidgrenT. Te... 478 SwedenEnglandSwedenSwedenSwedenSwedenGuineaSwe... 11030000 39000 LCBCFRMLBLCMRCBGKCMCMSTCBLMGKRBCMLBRWCAMLMGK 944 805 856 ... 847 1132 920 842 816 342 357 369 337 363
Śląsk Wrocław 172358 M. RobakP. CelebanR. PichA. PiechM. ChrapekAug... 628 PolandPolandSlovakiaPolandPolandPortugalIranPo... 9170000 50000 LSRCBLMRSLDMCDMRMRBLBRDMLBLCBGKRBCDMCBGKCMSTCD... 1058 1054 1289 ... 1150 1314 1047 1161 1129 408 403 367 394 403

650 rows × 41 columns

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

Давайте обратимся по индексу к какой-то из строк получившегося датафрейма:

grouped_df.loc['Ajax']
Unnamed: 0                                                     26041
Name               H. ZiyechM. de LigtF. de JongN. TagliaficoD. B...
Age                                                              275
Nationality        MoroccoNetherlandsNetherlandsArgentinaNetherla...
Value                                                      152250000
Wage                                                          158000
Position                               RAMRCBLDMLBLBRWSTCBRBCMLBLWCM
Crossing                                                         844
Finishing                                                        723
HeadingAccuracy                                                  848
ShortPassing                                                     940
Volleys                                                          696
Dribbling                                                        932
Curve                                                            779
FKAccuracy                                                       680
LongPassing                                                      878
BallControl                                                      951
Acceleration                                                     944
SprintSpeed                                                      969
Agility                                                          969
Reactions                                                        924
Balance                                                          918
ShotPower                                                        876
Jumping                                                          915
Stamina                                                          974
Strength                                                         896
LongShots                                                        720
Aggression                                                       847
Interceptions                                                    801
Positioning                                                      813
Vision                                                           881
Penalties                                                        710
Composure                                                        929
Marking                                                          750
StandingTackle                                                   814
SlidingTackle                                                    756
GKDiving                                                         150
GKHandling                                                       130
GKKicking                                                        139
GKPositioning                                                    155
GKReflexes                                                       129
Name: Ajax, dtype: object

Таким образом, мы получили серию, где индекс содержит все параметры, которые можно было просуммировать, а значения серии — суммы параметров для всех игроков ФК "Ajax".

Теперь мы можем получить сумму зарплат игроков этого футбольного клуба:

grouped_df.loc['Ajax']['Wage']
158000

Тут важно заметить, что особого смысла суммировать другие параметры нет. Например, что нам даёт сумма возрастов? Это неинформативная метрика, а значит смысла её подсчитывать нет. Поэтому мы можем ограничить список наших параметров и при группировке осуществлять суммирование только по параметру "Wage" (заработная плата):

grouped_df = df.groupby('Club')['Wage'].sum()
grouped_df
Club
 SSV Jahn Regensburg      90000
1. FC Heidenheim 1846     76000
1. FC Kaiserslautern      33000
1. FC Köln                92000
1. FC Magdeburg           84000
                          ...  
Zagłębie Sosnowiec        27000
Çaykur Rizespor          118000
Örebro SK                 36000
Östersunds FK             39000
Śląsk Wrocław             50000
Name: Wage, Length: 650, dtype: int64
# лучше так:
grouped_df = df.groupby('Club').agg({'Wage': 'sum'})
grouped_df
Wage
Club
SSV Jahn Regensburg 90000
1. FC Heidenheim 1846 76000
1. FC Kaiserslautern 33000
1. FC Köln 92000
1. FC Magdeburg 84000
... ...
Zagłębie Sosnowiec 27000
Çaykur Rizespor 118000
Örebro SK 36000
Östersunds FK 39000
Śląsk Wrocław 50000

650 rows × 1 columns

Уже лучше!

Но помните наш исходный вопрос: "В каком клубе самая высокая зарплата?"

Для ответа на этот вопрос нам достаточно лишь отсортировать полученные данные по убыванию суммы зарплат с помощью функции sort_values:

# параметр ascending=False указывает, что данные надо сортировать по убыванию
grouped_df = df \
               .groupby('Club') \
               .agg({'Wage': 'sum'}) \
               .sort_values(by="Wage", ascending=False)

grouped_df.head(5)
Wage
Club
Real Madrid 4138000
FC Barcelona 3967000
Manchester City 3097000
Manchester United 2357000
Juventus 2335000

И это Real Madrid, что вполне ожидаемо!

Давайте рассмотрим ещё несколько примеров использования функции groupby.

Например, построим такую таблицу, где сгруппируем игроков по национальностям (Nationality) и посчитаем среднюю зарплату, средний возраст и среднюю силу удара. Ну а что, вдруг это всё как-то взаимосвязано?

Для подсчета среднего мы будем использовать агрегирующую функцию mean:

df.groupby('Nationality')[['Wage','Age','ShotPower']].mean()
Wage Age ShotPower
Nationality
Afghanistan 1250.000000 22.500000 53.750000
Albania 5931.034483 23.689655 54.551724
Algeria 15810.810811 27.027027 56.567568
Andorra 1000.000000 28.000000 58.000000
Angola 7100.000000 24.700000 63.700000
... ... ... ...
Uzbekistan 9000.000000 29.500000 71.500000
Venezuela 6611.111111 23.638889 57.222222
Wales 9529.411765 24.754902 48.558824
Zambia 2833.333333 21.833333 66.833333
Zimbabwe 5000.000000 26.555556 62.888889

156 rows × 3 columns

Далее отсортируем по убыванию усредненной зарплаты:

df \
  .groupby('Nationality')[['Wage','Age','ShotPower']] \
  .mean() \
  .sort_values('Wage', ascending=False) \
  .head(10)
Wage Age ShotPower
Nationality
Dominican Republic 71000.000000 23.000000 75.500000
Egypt 35545.454545 25.818182 59.363636
Gabon 28900.000000 26.400000 56.900000
Croatia 26722.222222 24.819444 54.305556
Equatorial Guinea 25666.666667 28.000000 55.333333
Belgium 20024.390244 24.030488 56.390244
Ecuador 18333.333333 24.619048 60.666667
Uruguay 17590.361446 26.771084 56.192771
Brazil 17371.158392 27.898345 58.203310
Algeria 15810.810811 27.027027 56.567568

Что?! Доминиканская республика? Очень странно, давайте поближе посмотрим на данные по этой стране:

df.query("Nationality == 'Dominican Republic'")[['Name','Club','Wage','Age','ShotPower']]
Name Club Wage Age ShotPower
291 Mariano Real Madrid 140000 24 85
6279 L. Quezada Córdoba CF 2000 22 66

Теперь всё ясно. В нашей выборке только два футболиста из этой страны, один из них играет в клубе "Real Madrid" и получает 140000 евро, а другой в испанском клубе второго дивизиона с зарплатой в 70 раз ниже! Поэтому среднее и получилось таким высоким.

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

Посчитайте среднюю зарплату (Wage) и цену (Value) игроков разных позиций (Position). Представители какой позиции имеют самую высокую среднюю цену?

Какова средняя зарплата футболистов на данной позиции?

В предыдущих примерах мы использовали такие агрегирующие функции, как sum (сумма) и mean (среднее). Давайте рассмотрим, какие ещё функции можно использовать при группировке данных.

Функция nunique, которая позволяет посчитать количество уникальных значений по серии. Её лучше всего применять к тем колонкам датафрейма, в которых хранятся категорийные данные:

df.groupby('Nationality')[['Club','Name']].nunique()
Club Name
Nationality
Afghanistan 4 4
Albania 26 29
Algeria 33 37
Andorra 1 1
Angola 9 10
... ... ...
Uzbekistan 2 2
Venezuela 34 36
Wales 56 101
Zambia 5 6
Zimbabwe 8 9

156 rows × 2 columns

Функция count, с помощью которой можно посчитать количество элементов в группе. То есть результат её будет такой же, как у функции value_counts:

df.groupby('Club')['Name'].count()
Club
 SSV Jahn Regensburg     24
1. FC Heidenheim 1846    20
1. FC Kaiserslautern     23
1. FC Köln               10
1. FC Magdeburg          21
                         ..
Zagłębie Sosnowiec       25
Çaykur Rizespor          22
Örebro SK                26
Östersunds FK            20
Śląsk Wrocław            24
Name: Name, Length: 650, dtype: int64
# либо так:
df \
  .groupby('Club') \
  .agg({'Name' : "count"})
Name
Club
SSV Jahn Regensburg 24
1. FC Heidenheim 1846 20
1. FC Kaiserslautern 23
1. FC Köln 10
1. FC Magdeburg 21
... ...
Zagłębie Sosnowiec 25
Çaykur Rizespor 22
Örebro SK 26
Östersunds FK 20
Śląsk Wrocław 24

650 rows × 1 columns

Функция median, с помощью которой можно посчитать медианное значение:

df.groupby('Club')['Dribbling'].median()
Club
 SSV Jahn Regensburg     57.5
1. FC Heidenheim 1846    59.5
1. FC Kaiserslautern     54.0
1. FC Köln               60.5
1. FC Magdeburg          53.0
                         ... 
Zagłębie Sosnowiec       58.0
Çaykur Rizespor          62.0
Örebro SK                55.0
Östersunds FK            61.5
Śląsk Wrocław            54.5
Name: Dribbling, Length: 650, dtype: float64
# либо так:
df \
  .groupby('Club') \
  .agg({'Dribbling' : "median"})
Dribbling
Club
SSV Jahn Regensburg 57.5
1. FC Heidenheim 1846 59.5
1. FC Kaiserslautern 54.0
1. FC Köln 60.5
1. FC Magdeburg 53.0
... ...
Zagłębie Sosnowiec 58.0
Çaykur Rizespor 62.0
Örebro SK 55.0
Östersunds FK 61.5
Śląsk Wrocław 54.5

650 rows × 1 columns

Функция max, с помощью которой можно посчитать максимальное значение внутри группы:

df.groupby('Club')['Strength'].max()
Club
 SSV Jahn Regensburg     92
1. FC Heidenheim 1846    86
1. FC Kaiserslautern     85
1. FC Köln               76
1. FC Magdeburg          86
                         ..
Zagłębie Sosnowiec       84
Çaykur Rizespor          81
Örebro SK                85
Östersunds FK            88
Śląsk Wrocław            85
Name: Strength, Length: 650, dtype: int64
# либо так:
df \
  .groupby('Club', as_index=False) \
  .agg({'Strength': 'max'})
Club Strength
0 SSV Jahn Regensburg 92
1 1. FC Heidenheim 1846 86
2 1. FC Kaiserslautern 85
3 1. FC Köln 76
4 1. FC Magdeburg 86
... ... ...
645 Zagłębie Sosnowiec 84
646 Çaykur Rizespor 81
647 Örebro SK 85
648 Östersunds FK 88
649 Śląsk Wrocław 85

650 rows × 2 columns

Функция min, с помощью которой можно посчитать минимальное значение внутри группы:

df.groupby('Club')['Balance'].min()
Club
 SSV Jahn Regensburg     29
1. FC Heidenheim 1846    22
1. FC Kaiserslautern     29
1. FC Köln               31
1. FC Magdeburg          19
                         ..
Zagłębie Sosnowiec       28
Çaykur Rizespor          39
Örebro SK                34
Östersunds FK            32
Śląsk Wrocław            31
Name: Balance, Length: 650, dtype: int64
# либо так:
df \
  .groupby('Club') \
  .agg({'Balance': "min"})
Balance
Club
SSV Jahn Regensburg 29
1. FC Heidenheim 1846 22
1. FC Kaiserslautern 29
1. FC Köln 31
1. FC Magdeburg 19
... ...
Zagłębie Sosnowiec 28
Çaykur Rizespor 39
Örebro SK 34
Östersunds FK 32
Śląsk Wrocław 31

650 rows × 1 columns

Задание 1

Посчитайте среднюю (mean) и медианную (median) зарплату (Wage) футболистов из разных клубов (Club). В скольких клубах средняя и медианная зарплаты совпадают?

Подсказка: чтобы в процессе группировки применить к данным одновременно две агрегирующие функции, необходимо указать их как аргументы метода agg:

df.groupby(столбец_для_группировки)[столбцы_для_отображения].agg(['функция_1', 'функция_2'])

либо:

df.groupby(столбец_для_группировки).agg({'столбец_для_отображения':['функция_1', 'функция_2'])
# code

Задание 2

Продолжаем работать с клубами, в которых средняя зарплата совпадает с медианной. Каков максимальный размер средней зарплаты в этой группе клубов?

# code

Как называется клуб, где игроки получают такую зарплату?

# code

Задание 3

С помощью функции groupby посчитайте сумму зарплат (Wage) футболистов клуба (Club) "Chelsea".

# code

Задание 4

Определите максимальную зарплату футболиста национальности (Nationality) Аргентина ("Argentina") в возрасте 20 лет.

# code

Задание 5

Определите максимальную зарплату футболиста национальности (Nationality) Аргентина ("Argentina") в возрасте 30 лет.

# code

Задание 6

Определите минимальную зарплату футболиста национальности (Nationality) Аргентина ("Argentina") в возрасте 30 лет.

# code

Задание 7

Определите максимальную силу (Strength) и баланс (Balance) среди игроков клуба (Club) "FC Barcelona" из Аргентины ("Argentina"). Ответ через точку с запятой без пробела.

# code