2022年5月21日土曜日

NBAデータから歴代得点王ランキングを出してみる

馴染みのあるデータや好きなスポーツのデータを扱ったりするとデータフレームを習得するのも楽しめていいですね。

今回はおなじくkaggleの NBA Players stats since 1950 から Seasons_Stats.csv を使用して歴代得点王を取り出したいと思います。


#! /usr/bin/env python

# -*- coding:utf-8 -*-

#
import pandas as pd
import numpy as np

filename = "../data/Seasons_Stats.csv"

print("[NBA]")
print()

df = pd.read_csv(filename, index_col=0)

print()

# 年間得点の多い順にソート
porder = df.sort_values('PTS', ascending=False)

# Year, Player, PTSのみのデータフレームにする
points = porder.loc[:, ['Year', 'Player', 'PTS']]

# Year, Player, PTSのみのDataFrame 数
print(points.shape)
print()

# 欠損値の削除
points = points.dropna()
print(points.shape)
print()

# 見やすいようにfloatからintへの変換
point = points.astype({'Year': 'int64', 'PTS': 'int64'})
print(points.dtypes)
print()
print(points.info())
print()

# 得点ランキングトップ50を表示する
points.reset_index(drop=True, inplace=True)
points.index = np.arange(1, len(points)+1)
print(points.head(50))


まず、年間得点(PTS)を sort_values() を使い得点の多い順(逆ソート)します。
得点だけのランキングなので記録年数(Year)、選手名(Player)、年間得点(PTS)だけのデータフレームを loc を使って切り出します。

このままだと年と年間得点もデータ型が float64 なのでintに変えたいと思いますが、欠損値があるのでデータ変換できません。
そこで先に欠損値行をdropna() で消します。
元の数(24691, 3) から (24624, 3) に減りました。
これで astype() を使い 年と年間得点を int に変換します。

もう一つソートされてもインデックスがそのままだと何の数字か分からないのでインデックスを reset_index() で振り直します。
インデックスをランキングにしたいなら0基準より1から数えたほうがいいでしょう。

すべて整ったら歴代得点ランキングトップ50を取り出してみます。

    Year                Player   PTS
1   1962     Wilt Chamberlain*  4029
2   1963     Wilt Chamberlain*  3586
3   1987       Michael Jordan*  3041
4   1961     Wilt Chamberlain*  3033
5   1964     Wilt Chamberlain*  2948
6   1988       Michael Jordan*  2868
7   2006           Kobe Bryant  2832
8   1975           Bob McAdoo*  2831
9   1972  Kareem Abdul-Jabbar*  2822
10  1967           Rick Barry*  2775
11  1990       Michael Jordan*  2753
12  1973       Tiny Archibald*  2719
13  1963         Elgin Baylor*  2719
14  1960     Wilt Chamberlain*  2707
15  1966     Wilt Chamberlain*  2649
16  1989       Michael Jordan*  2633
17  1971  Kareem Abdul-Jabbar*  2596
18  2014          Kevin Durant  2593
19  1980        George Gervin*  2585
20  1991       Michael Jordan*  2580
21  2017     Russell Westbrook  2558
22  1982        George Gervin*  2551
23  1993       Michael Jordan*  2541
24  1990          Karl Malone*  2540
25  1961         Elgin Baylor*  2538
26  1965     Wilt Chamberlain*  2534
27  1982         Moses Malone*  2520
28  1962         Walt Bellamy*  2495
29  1996       Michael Jordan*  2491
30  1964      Oscar Robertson*  2480
31  2006          LeBron James  2478
32  1966           Jerry West*  2476
33  2010          Kevin Durant  2472
34  2003           Kobe Bryant  2461
35  1982       Adrian Dantley*  2457
36  1981       Adrian Dantley*  2452
37  1975           Rick Barry*  2450
38  1962      Oscar Robertson*  2432
39  1997       Michael Jordan*  2431
40  2007           Kobe Bryant  2430
41  1962           Bob Pettit*  2429
42  1976           Bob McAdoo*  2427
43  1984       Adrian Dantley*  2418
44  1986         Alex English*  2414
45  1967      Oscar Robertson*  2412
46  2003         Tracy McGrady  2407
47  1992       Michael Jordan*  2404
48  1988    Dominique Wilkins*  2397
49  2009           Dwyane Wade  2386
50  1994       David Robinson*  2383


 Wilt Chamberlainの年間得点が異常と言われるほど凄い数字だというのが分かります。






 

NBAデータをDataFrameを使ってグループ分けをする

Pandasのデータフレームはデータ分析に適しています。

NBAデータから自分の取り出したいデータに分けてみます。

データ元は便利な kaggle から「NBA Players stats since 1950」というデータをお借りします。


Seasons_Stats.csvには1950-2017年まで(24691, 53)件という選手の膨大なデータがあります。


 #! /usr/bin/env python
 # -*- coding:utf-8 -*-
 
 #import pandas as pd
 import numpy as np
 
 filename = "Seasons_Stats.csv"
 
 df = pd.read_csv(filename)
 
 print(df.head())
 print()
 print(df.shape)
 print()


 Unnamed: 0    Year         Player Pos   Age  ...    STL   BLK    TOV     PF     PTS
9547        9547  1990.0     Mark Acres   C  27.0  ...   36.0  25.0   70.0  248.0   362.0
9548        9548  1990.0  Michael Adams  PG  27.0  ...  121.0   3.0  141.0  133.0 1221.0
9549        9549  1990.0   Mark Aguirre  SF  30.0  ...   34.0  19.0  121.0  201.0  1099.0
9550        9550  1990.0    Danny Ainge  PG  30.0  ...  113.0  18.0  185.0  238.0  1342.0
9551        9551  1990.0    Mark Alarie  PF  26.0  ...   60.0  39.0  101.0  219.0   860.0

(24691, 53)



これでは流石に大きすぎるので1990年代のデータだけ取り出してみましょう。

y1990 = df[df['Year'] == 1990]
y1990 = y1990.drop(y1990.columns[0], axis=1)
y1990 = y1990.reset_index(drop=True)

print(y1990.head())
print()
print(y1990.shape)
先頭のインデックスはいらないのでdrop関数で弾いて、reset_index関数で振り直しています。
引数のdrop=Trueは元のインデックスを残さないためのものです。


     Year         Player Pos   Age   Tm  ...    STL   BLK    TOV     PF     PTS
0  1990.0     Mark Acres   C  27.0  ORL  ...   36.0  25.0   70.0  248.0   362.0
1  1990.0  Michael Adams  PG  27.0  DEN  ...  121.0   3.0  141.0  133.0  1221.0
2  1990.0   Mark Aguirre  SF  30.0  DET  ...   34.0  19.0  121.0  201.0  1099.0
3  1990.0    Danny Ainge  PG  30.0  SAC  ...  113.0  18.0  185.0  238.0  1342.0
4  1990.0    Mark Alarie  PF  26.0  WSB  ...   60.0  39.0  101.0  219.0   860.0

(459, 52)

これで1990年のデータが取り出せました。