☆ M. Anzai… !! Je veux analyser les données …… Partie 1 Préparation des données ☆ Analysons les statistiques des joueurs NBA (résultats) avec Python. basketball

Tout le monde à travers le pays aime le basket-ball, bonjour. Je m'appelle Hikoichi Aida. Je travaille généralement en tant que manager et data scientist dans une équipe de basket-ball d'un lycée, analysant diverses données.

Cette fois, j'aimerais analyser les statistiques des joueurs (résultats) de la NBA, qui est une ligue de basket-ball professionnelle aux États-Unis. C'est facile à analyser, mais veuillez rester en contact.

Le premier concerne le scraping et le prétraitement car il s'agit de la préparation des données. Je ne sais pas quand auront lieu la deuxième session et les suivantes, pardonnez-moi. Ce ne sera peut-être pas pour toujours.

environnement

J'ai utilisé Google Colaboratory. Le processus introduit cette fois ne peut être utilisé qu'avec la bibliothèque préinstallée. C'est très pratique.

Collecte de données

Grattage

Lorsque je cherchais quoi faire avec la partie collecte de données, j'ai trouvé l'article de blog suivant.

Cet article et le contenu sont presque les mêmes, mais j'ai pensé que la taille et le poids du joueur pourraient être grattés, j'ai donc inclus l'URL de la page personnelle du joueur comme cible de grattage. Étant donné que l'enregistrement représentant le nom de la colonne est inséré à intervalles réguliers, cet enregistrement est ignoré.

data = pd.DataFrame()
years = [i for i in range(2000, 2002)]
for year in years:
    url = "https://www.basketball-reference.com/leagues/NBA_{}_per_game.html".format(year)
    # this is the HTML from the given URL
    html = urlopen(url)
    soup = BeautifulSoup(html)

    soup.findAll('tr', limit=2)
    # use getText()to extract the text we need into a list
    headers = [th.getText() for th in soup.findAll('tr', limit=2)[0].findAll('th')]
    # exclude the first column as we will not need the ranking order from Basketball Reference for the analysis
    headers = ['URL'] + headers[1:] + ['Year']

    rows = soup.findAll('tr')[1:]
    player_stats = [[rows[i].a.get('href')] + [td.getText() for td in rows[i].findAll('td')] for i in range(len(rows)) if (rows[i].findAll('td')) and (rows[i].a)]
    stats = pd.DataFrame(player_stats)
    stats['Year'] = str(year)
    stats.columns = headers
    data = pd.concat([data, stats])
data = data.dropna()

Voici un exemple de page à gratter.

Toutes les statistiques des joueurs qui ont participé à cette saison sont sur le site d'une page, donc je pense que vous pouvez collecter suffisamment de données même si vous les faites glisser et les copiez dans un logiciel de calcul de table tel qu'Excel.

Cette fois, nous avons ciblé des données sur 20 ans (2000-2019). Le résultat du grattage ressemble à ceci.

URL Player Pos Age Tm G GS MP FG FGA FG% 3P 3PA 3P% 2P 2PA 2P% eFG% FT FTA FT% ORB DRB TRB AST STL BLK TOV PF PTS Year
0 /players/a/abdulta01.html Tariq Abdul-Wahad SG 25 TOT 61 56 25.9 4.5 10.6 .424 0.0 0.4 .130 4.4 10.2 .435 .426 2.4 3.2 .756 1.7 3.1 4.8 1.6 1.0 0.5 1.7 2.4 11.4 2000
1 /players/a/abdulta01.html Tariq Abdul-Wahad SG 25 ORL 46 46 26.2 4.8 11.2 .433 0.0 0.5 .095 4.8 10.7 .447 .435 2.5 3.3 .762 1.7 3.5 5.2 1.6 1.2 0.3 1.9 2.5 12.2 2000
2 /players/a/abdulta01.html Tariq Abdul-Wahad SG 25 DEN 15 10 24.9 3.4 8.7 .389 0.1 0.1 .500 3.3 8.6 .388 .393 2.1 2.8 .738 1.6 1.9 3.5 1.7 0.4 0.8 1.3 2.1 8.9 2000
3 /players/a/abdursh01.html Shareef Abdur-Rahim SF 23 VAN 82 82 39.3 7.2 15.6 .465 0.4 1.2 .302 6.9 14.4 .478 .477 5.4 6.7 .809 2.7 7.4 10.1 3.3 1.1 1.1 3.0 3.0 20.3 2000
4 /players/a/alexaco01.html Cory Alexander PG 26 DEN 29 2 11.3 1.0 3.4 .286 0.3 1.2 .257 0.7 2.2 .302 .332 0.6 0.8 .773 0.3 1.2 1.4 2.0 0.8 0.1 1.0 1.3 2.8 2000
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
703 /players/z/zellety01.html Tyler Zeller C 29 MEM 4 1 20.5 4.0 7.0 .571 0.0 0.0 4.0 7.0 .571 .571 3.5 4.5 .778 2.3 2.3 4.5 0.8 0.3 0.8 1.0 4.0 11.5 2019
704 /players/z/zizican01.html Ante Žižić C 22 CLE 59 25 18.3 3.1 5.6 .553 0.0 0.0 3.1 5.6 .553 .553 1.6 2.2 .705 1.8 3.6 5.4 0.9 0.2 0.4 1.0 1.9 7.8 2019
705 /players/z/zubaciv01.html Ivica Zubac C 21 TOT 59 37 17.6 3.6 6.4 .559 0.0 0.0 3.6 6.4 .559 .559 1.7 2.1 .802 1.9 4.2 6.1 1.1 0.2 0.9 1.2 2.3 8.9 2019
706 /players/z/zubaciv01.html Ivica Zubac C 21 LAL 33 12 15.6 3.4 5.8 .580 0.0 0.0 3.4 5.8 .580 .580 1.7 2.0 .864 1.6 3.3 4.9 0.8 0.1 0.8 1.0 2.2 8.5 2019
707 /players/z/zubaciv01.html Ivica Zubac C 21 LAC 26 25 20.2 3.8 7.2 .538 0.0 0.0 3.8 7.2 .538 .538 1.7 2.3 .733 2.3 5.3 7.7 1.5 0.4 0.9 1.4 2.5 9.4 2019

Prétraitement

Valeur manquante

Les statistiques qui représentent la probabilité telle que FG% (pensez taux de réussite des buts sur le terrain = taux de réussite des tirs) semblent être vides si le nombre de tirs d'essai est de 0. Remplacez par NaN.

data = data.replace(r'^\s*$', np.NaN, regex=True)

Changement de type de données

Le type de données est une chaîne de caractères. Convertissez les données que vous souhaitez traiter comme un nombre en flottant. Il y a des données avec seulement des entiers, mais comme c'est gênant, je vais tout faire flotter. Avant le changement, la note exprimée en pourcentage est écrite sous la forme «.XXX», et elle ne peut pas être convertie en un nombre tel quel, alors ajoutez «0» au début.

add_zero_cols = [col for col in data.columns if '%' in col]
num_cols = ['Age'] + list(data.columns[5:-1])

for col in add_zero_cols:
    data[col] = '0' + data[col]
for col in num_cols:
    data[col] = data[col].astype(float)

Allons vérifier. Affiche les 10 meilleurs scores moyens.

data.sort_values('PTS', ascending=False)[['Player', 'PTS', 'Year']].head(10)
Player PTS Year
11135 James Harden 36.1 2019
3266 Kobe Bryant* 35.4 2006
3428 Allen Iverson* 33.0 2006
1813 Tracy McGrady* 32.1 2003
7954 Kevin Durant 32.0 2014
3818 Kobe Bryant* 31.6 2007
10167 Russell Westbrook 31.6 2017
1249 Allen Iverson* 31.4 2002
3442 LeBron James 31.4 2006
715 Allen Iverson* 31.1 2001

Il ne semble y avoir aucun problème. Il existe de nombreuses superstars bien connues au Japon telles que James Harden, Allen Iverson et Corby Bryant.

J'ai jeté un coup d'œil sur la page de la source de données pour voir ce que la marque * après le nom représente, mais je n'étais pas sûr: sweat_smile: Il peut représenter un joueur qui est dans le Hall of Fame.

Données supplémentaires Taille / poids

Nous avons également collecté des données sur la taille et le poids à partir de l'URL de la page personnelle qui était également incluse dans l'élément de grattage. (Comme il peut être collecté en modifiant légèrement le code au début, le code des données supplémentaires est omis)

Enfin, ces données sont prêtes. (Les colonnes Poids et Hauteur ont été ajoutées à l'extrême droite)

Player Pos Age Tm G GS MP FG FGA FG% 3P 3PA 3P% 2P 2PA 2P% eFG% FT FTA FT% ORB DRB TRB AST STL BLK TOV PF PTS Year Weight Height
0 Tariq Abdul-Wahad SG 25.0 TOT 61.0 56.0 25.9 4.5 10.6 0.424 0.0 0.4 0.130 4.4 10.2 0.435 0.426 2.4 3.2 0.756 1.7 3.1 4.8 1.6 1.0 0.5 1.7 2.4 11.4 2000 101.24 1.98
3 Shareef Abdur-Rahim SF 23.0 VAN 82.0 82.0 39.3 7.2 15.6 0.465 0.4 1.2 0.302 6.9 14.4 0.478 0.477 5.4 6.7 0.809 2.7 7.4 10.1 3.3 1.1 1.1 3.0 3.0 20.3 2000 102.15 2.06
5 Ray Allen* SG 24.0 MIL 82.0 82.0 37.4 7.8 17.2 0.455 2.1 5.0 0.423 5.7 12.2 0.468 0.516 4.3 4.9 0.887 1.0 3.4 4.4 3.8 1.3 0.2 2.2 2.3 22.1 2000 93.07 1.96
7 John Amaechi C 29.0 ORL 80.0 53.0 21.1 3.8 8.8 0.437 0.0 0.1 0.167 3.8 8.7 0.439 0.438 2.8 3.6 0.766 0.8 2.6 3.3 1.2 0.4 0.5 1.7 2.0 10.5 2000 122.58 2.08
8 Derek Anderson SG 25.0 LAC 64.0 58.0 34.4 5.9 13.4 0.438 0.9 2.8 0.309 5.0 10.7 0.472 0.470 4.2 4.8 0.877 1.3 2.8 4.0 3.4 1.4 0.2 2.6 2.3 16.9 2000 88.08 1.96
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
11561 Delon Wright PG 26.0 TOT 75.0 13.0 22.7 3.2 7.4 0.434 0.7 2.2 0.298 2.6 5.2 0.492 0.478 1.6 2.0 0.793 0.9 2.6 3.5 3.3 1.2 0.4 1.0 1.4 8.7 2019 83.08 1.96
11566 Thaddeus Young PF 30.0 IND 81.0 81.0 30.7 5.5 10.4 0.527 0.6 1.8 0.349 4.8 8.6 0.564 0.557 1.1 1.7 0.644 2.4 4.1 6.5 2.5 1.5 0.4 1.5 2.4 12.6 2019 99.88 2.03
11567 Trae Young PG 20.0 ATL 81.0 81.0 30.9 6.5 15.5 0.418 1.9 6.0 0.324 4.6 9.6 0.477 0.480 4.2 5.1 0.829 0.8 2.9 3.7 8.1 0.9 0.2 3.8 1.7 19.1 2019 81.72 1.86
11572 Ante Žižić C 22.0 CLE 59.0 25.0 18.3 3.1 5.6 0.553 0.0 0.0 NaN 3.1 5.6 0.553 0.553 1.6 2.2 0.705 1.8 3.6 5.4 0.9 0.2 0.4 1.0 1.9 7.8 2019 115.32 2.08
11573 Ivica Zubac C 21.0 TOT 59.0 37.0 17.6 3.6 6.4 0.559 0.0 0.0 NaN 3.6 6.4 0.559 0.559 1.7 2.1 0.802 1.9 4.2 6.1 1.1 0.2 0.9 1.2 2.3 8.9 2019 108.96 2.13

Au fait, les 10 plus hauts sommets des 20 dernières années

df.groupby(['Player']).max().reset_index().sort_values('Height', ascending=False)[['Player', 'Year', 'Height', 'Weight']].head(10)
Player Year Height Weight
672 Gheorghe Mureșan 2000 2.31 137.56
1641 Shawn Bradley 2005 2.29 106.69
1890 Yao Ming* 2011 2.29 140.74
1653 Sim Bhullar 2015 2.26 163.44
1442 Pavel Podkolzin 2006 2.26 118.04
1656 Slavko Vraneš 2004 2.26 124.85
1519 Rik Smits 2000 2.24 113.50
172 Boban Marjanović 2019 2.24 131.66
1449 Peter John Ramos 2005 2.21 124.85
583 Edy Tavares 2017 2.21 118.04

L'unité est le m (mètre). La troisième place est celle de Yao Min, qui s'appelait aussi la Grande Muraille de Mari. La hauteur est trop grande.

fin

Maintenant que les données sont prêtes, j'aimerais les visualiser la prochaine fois.

prime

Top 10 de l'assistance moyenne

data.sort_values('AST', ascending=False)[['Player', 'AST', 'Year']].head(10)
Player AST Year
6617 Deron Williams 12.8 2011
7061 Rajon Rondo 11.7 2012
9486 Rajon Rondo 11.7 2016
4085 Steve Nash* 11.6 2007
4686 Chris Paul 11.6 2008
2977 Steve Nash* 11.5 2005
6440 Steve Nash* 11.4 2011
6509 Rajon Rondo 11.2 2011
9819 James Harden 11.2 2017
7641 Rajon Rondo 11.1 2013

Top 10 des rebonds moyens

data.sort_values('TRB', ascending=False)[['Player', 'TRB', 'Year']].head(10)
Player TRB Year
7236 Earl Barron 18.0 2013
651 Danny Fortson 16.3 2001
10372 Andre Drummond 16.0 2018
11056 Andre Drummond 15.6 2019
1974 Ben Wallace 15.4 2003
6391 Kevin Love 15.2 2011
10537 DeAndre Jordan 15.2 2018
8695 DeAndre Jordan 15.0 2015
9163 Andre Drummond 14.8 2016
6894 Dwight Howard 14.5 2012

Il semble que les joueurs n'ayant pas atteint le nombre de parties spécifié doivent être exclus.

Recommended Posts

☆ M. Anzai… !! Je veux analyser les données …… Partie 1 Préparation des données ☆ Analysons les statistiques des joueurs NBA (résultats) avec Python. basketball
Je veux pouvoir analyser des données avec Python (partie 3)
Je veux pouvoir analyser des données avec Python (partie 1)
Je veux pouvoir analyser des données avec Python (partie 4)
Je veux pouvoir analyser des données avec Python (partie 2)
Je veux analyser les journaux avec Python
Je veux hériter de l'arrière avec la classe de données python
J'en ai marre de Python, alors j'ai essayé d'analyser les données avec nehan (je veux aller vivre même avec Corona) -Partie 2)
J'en ai marre de Python, alors j'ai essayé d'analyser les données avec nehan (je veux aller vivre même avec Corona) -Partie 1)
[Python] Je souhaite utiliser l'option -h avec argparse
Je veux déboguer avec Python
Je veux connaître la météo avec LINE bot avec Heroku + Python
[Pandas] J'ai essayé d'analyser les données de ventes avec Python [Pour les débutants]
Je veux gérer la rime part1
Je veux gérer la rime part3
Je veux jouer avec aws avec python
J'ai essayé d'obtenir et d'analyser les données statistiques de la nouvelle Corona avec Python: données de l'Université John's Hopkins
J'ai commencé l'apprentissage automatique avec Python (j'ai également commencé à publier sur Qiita) Préparation des données
Je veux gérer la rime part2
Je veux gérer la rime part5
Je veux gérer la rime part4
Je veux utiliser MATLAB feval avec python
J'ai essayé de sauvegarder les données avec discorde
Je veux frapper 100 sciences des données avec Colaboratory
Je veux faire un jeu avec Python
Je veux gérer la rime part7 (BOW)
J'ai essayé d'obtenir des données CloudWatch avec Python
Je souhaite utiliser le répertoire temporaire avec Python2
#Unresolved Je veux compiler gobject-introspection avec Python3
Je veux résoudre APG4b avec Python (chapitre 2)
Je veux écrire dans un fichier avec Python
Je veux afficher la progression en Python!
Je souhaite utiliser une source de données python dans Re: Dash pour obtenir les résultats de la requête.
Je veux gérer l'optimisation avec python et cplex
J'ai essayé de toucher un fichier CSV avec Python
Je veux travailler avec un robot en python.
Je veux écrire en Python! (3) Utiliser des simulacres
Je veux AWS Lambda avec Python sur Mac!
J'ai essayé de résoudre le problème avec Python Vol.1
Je veux gérer la rime part6 (organiser une fois)
Je veux utiliser le jeu de données R avec python
Je veux faire fonctionner un ordinateur quantique avec Python
Je veux gérer la rime part8 (fini une fois)
Je connais? Analyse de données à l'aide de Python ou de choses que vous souhaitez utiliser quand vous le souhaitez avec numpy
J'ai essayé d'analyser les données du tournoi de football de la Coupe du monde de football en Russie avec l'action de football
J'ai essayé de trouver l'entropie de l'image avec python
Je veux initialiser si la valeur est vide (python)
J'ai essayé de simuler la propagation de l'infection avec Python
Je souhaite spécifier une autre version de Python avec pyvenv
Je voulais résoudre le concours de programmation Panasonic 2020 avec Python
J'ai essayé de créer diverses "données factices" avec Python faker
Je veux automatiser ssh en utilisant la commande expect! partie 2
maya Python Je veux réparer à nouveau l'animation cuite.
Je veux changer le drapeau japonais en drapeau des Palaos avec Numpy
[Part.2] Exploration avec Python! Cliquez sur la page Web pour vous déplacer!
Je veux assister automatiquement à des cours en ligne avec Python + Selenium!
Je veux connaître la nature de Python et pip