☆ Mr. Anzai… !! Ich möchte die Daten analysieren …… Teil 1 Datenvorbereitung ☆ Analysieren wir die NBA-Spielerstatistiken (Ergebnisse) mit Python. Basketball

Jeder im ganzen Land des Liebesbasketballs, hallo. Ich heiße Hikoichi Aida. Normalerweise arbeite ich als Manager und Datenwissenschaftler in einem Basketballteam der High School und analysiere verschiedene Daten.

Dieses Mal möchte ich die Spielerstatistiken (Ergebnisse) von NBA analysieren, einer professionellen Basketballliga in den USA. Es ist leicht zu analysieren, aber bitte bleiben Sie in Kontakt.

Das erste betrifft das Scraping und die Vorverarbeitung, da es sich um die Datenvorbereitung handelt. Ich weiß nicht, wann die zweite und die folgenden Sitzungen stattfinden werden, bitte verzeihen Sie mir. Es kann nicht für immer sein.

Umgebung

Ich habe Google Colaboratory verwendet. Der diesmal eingeführte Prozess kann nur mit der vorinstallierten Bibliothek ausgeführt werden. Es ist sehr praktisch.

Datensammlung

Schaben

Als ich suchte, was ich mit dem Datenerfassungsteil tun sollte, fand ich den folgenden Blog-Artikel.

Fast das gleiche wie in diesem Artikel, aber ich dachte, dass die Größe und das Gewicht der Spieler möglicherweise abgekratzt werden, also habe ich die URL der persönlichen Seite des Spielers als Scraping-Ziel angegeben. Da der Datensatz, der den Spaltennamen darstellt, in regelmäßigen Abständen eingefügt wird, wird dieser Datensatz übersprungen.

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()

Hier ist ein Beispiel für die Seite, die abgekratzt werden soll.

Alle Statistiken der Spieler, die an dieser Saison teilgenommen haben, befinden sich auf einer einseitigen Website. Ich denke, Sie können genügend Daten sammeln, auch wenn Sie sie ziehen und in eine Tabellenberechnungssoftware wie Excel kopieren.

Dieses Mal haben wir Daten für 20 Jahre (2000-2019) ins Visier genommen. Das Scraping-Ergebnis sieht so aus.

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

Vorverarbeitung

Fehlender Wert

Die Statistiken, die die Wahrscheinlichkeit wie FG% darstellen (Think Field Goal Success Rate = Shoot Success Rate), scheinen leer zu sein, wenn die Anzahl der Probeschüsse 0 beträgt. Durch NaN ersetzen.

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

Datentypänderung

Der Datentyp ist eine Zeichenfolge. Konvertieren Sie die Daten, die Sie behandeln möchten, in eine schwebende Zahl. Einige Daten sind nur Ganzzahlen, aber es ist problematisch, also werde ich sie alle schweben lassen. Vor der Änderung wird die als Prozentsatz ausgedrückte Note als ".XXX" geschrieben und kann nicht wie sie ist in eine Zahl umgewandelt werden. Fügen Sie daher am Anfang "0" hinzu.

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)

Lass uns nachsehen. Zeigt die Top 10 Durchschnittswerte an.

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

Es scheint kein Problem zu geben. In Japan gibt es viele bekannte Superstars wie James Harden, Allen Iverson und Corby Bryant.

Ich habe einen kurzen Blick auf die Datenquellenseite geworfen, um zu sehen, was die Markierung * nach dem Namen darstellt, war mir aber nicht sicher: heat_smile: Es kann einen Spieler darstellen, der sich in der Hall of Fame befindet.

Zusätzliche Daten Größe / Gewicht

Wir haben auch Daten zu Größe und Gewicht über die URL der persönlichen Seite gesammelt, die zusätzlich im Scraping-Artikel enthalten war. (Da es durch geringfügiges Ändern des Codes am Anfang erfasst werden kann, wird der Code für zusätzliche Daten weggelassen.)

Schließlich sind solche Daten bereit. (Die Spalten Gewicht und Höhe wurden ganz rechts hinzugefügt.)

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

Übrigens die Top 10 Höhen der letzten 20 Jahre

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

Die Einheit ist m (Meter). Der dritte Platz ist Yao Min, der auch die Große Mauer von Mari genannt wurde. Die Höhe ist zu groß.

Ende

Nachdem die Daten fertig sind, möchte ich sie beim nächsten Mal visualisieren.

Bonus

Durchschnittlicher Assist Top 10

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 durchschnittliche Rebounds

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

Es scheint, dass Spieler, die die angegebene Anzahl von Spielen nicht erreicht haben, ausgeschlossen werden müssen.

Recommended Posts

☆ Mr. Anzai… !! Ich möchte die Daten analysieren …… Teil 1 Datenvorbereitung ☆ Analysieren wir die NBA-Spielerstatistiken (Ergebnisse) mit Python. Basketball
Ich möchte Daten mit Python analysieren können (Teil 3)
Ich möchte Daten mit Python analysieren können (Teil 1)
Ich möchte Daten mit Python analysieren können (Teil 4)
Ich möchte Daten mit Python analysieren können (Teil 2)
Ich möchte Protokolle mit Python analysieren
Ich möchte mit Python-Datenklasse nach hinten erben
Ich habe Python satt, also habe ich versucht, die Daten mit nehan zu analysieren (ich möchte sogar mit Corona live gehen) - Teil 2)
Ich habe Python satt, also habe ich versucht, die Daten mit nehan zu analysieren (ich möchte sogar mit Corona live gehen) - Teil 1)
[Python] Ich möchte die Option -h mit argparse verwenden
Ich möchte mit Python debuggen
Ich möchte das Wetter mit LINE bot feat.Heroku + Python wissen
[Pandas] Ich habe versucht, Verkaufsdaten mit Python zu analysieren. [Für Anfänger]
Ich möchte mit dem Reim Teil1 umgehen
Ich möchte mit dem Reim part3 umgehen
Ich möchte mit aws mit Python spielen
Ich habe versucht, die statistischen Daten der neuen Corona mit Python abzurufen und zu analysieren: Daten der Johns Hopkins University
Ich habe mit Python mit dem maschinellen Lernen begonnen (ich habe auch angefangen, in Qiita zu posten). Datenvorbereitung
Ich möchte mit dem Reim part2 umgehen
Ich möchte mit dem Reim part5 umgehen
Ich möchte mit dem Reim part4 umgehen
Ich möchte MATLAB feval mit Python verwenden
Ich habe versucht, die Daten mit Zwietracht zu speichern
Ich möchte 100 Datenwissenschaften mit Colaboratory schlagen
Ich möchte ein Spiel mit Python machen
Ich möchte mit dem Reim part7 (BOW) umgehen
Ich habe versucht, CloudWatch-Daten mit Python abzurufen
Ich möchte Temporäres Verzeichnis mit Python2 verwenden
#Unresolved Ich möchte Gobject-Introspection mit Python3 kompilieren
Ich möchte APG4b mit Python lösen (Kapitel 2)
Ich möchte mit Python in eine Datei schreiben
Ich möchte den Fortschritt in Python anzeigen!
Ich möchte eine Python-Datenquelle in Re: Dash verwenden, um Abfrageergebnisse zu erhalten
Ich möchte die Optimierung mit Python und CPlex behandeln
Ich habe versucht, eine CSV-Datei mit Python zu berühren
Ich möchte mit einem Roboter in Python arbeiten.
Ich möchte in Python schreiben! (3) Verwenden Sie Mock
Ich möchte Lambda mit Python auf Mac AWS!
Ich habe versucht, das Problem mit Python Vol.1 zu lösen
Ich möchte mit dem Reim part6 umgehen (einmal organisieren)
Ich möchte R-Datensatz mit Python verwenden
Ich möchte einen Quantencomputer mit Python betreiben
Ich möchte mit dem Reim part8 umgehen (einmal fertig)
Ich kenne? Datenanalyse mit Python oder Dingen, die Sie mit numpy verwenden möchten, wenn Sie möchten
Ich habe versucht, die Daten des Fußballturniers der FIFA Fussball-Weltmeisterschaft Russland mit Fußball zu analysieren
Ich habe versucht, die Entropie des Bildes mit Python zu finden
Ich möchte initialisieren, wenn der Wert leer ist (Python)
Ich habe versucht zu simulieren, wie sich die Infektion mit Python ausbreitet
Ich möchte eine andere Version von Python mit pyvenv angeben
Ich wollte den Panasonic Programming Contest 2020 mit Python lösen
Ich habe versucht, mit Python faker verschiedene "Dummy-Daten" zu erstellen
Ich möchte ssh mit dem Befehl expected automatisieren! Teil 2
maya Python Ich möchte die gebackene Animation wieder reparieren.
Ich möchte mit Numpy die japanische Flagge in die Palau-Flagge ändern
[Teil 2] Crawlen mit Python! Klicken Sie auf die Webseite, um sich zu bewegen!
Ich möchte automatisch an Online-Kursen mit Python + Selen teilnehmen!
Ich möchte die Natur von Python und Pip kennenlernen