2022年6月17日金曜日

NBA選手データを整える

 NBAはデータを豊富に提供しているので分析に適しています。

ただし、身長や体重が日本と異なる表記なので、日本で分かりやすいようにデータを変換してみます。

ついでに欠損値除去や微調整してデータを取り扱い安くします。


まず、元データ player_data.csv の中身を確認します。

filename = "player_data.csv"

df = pd.read_csv(filename)

print(df.head())
print()
print(df.shape)
print()
print(df.info())


                  name  year_start  year_end position height  weight        birth_date                                college

0       Alaa Abdelnaby        1991      1995      F-C   6-10   240.0     June 24, 1968                        Duke University

1      Zaid Abdul-Aziz        1969      1978      C-F    6-9   235.0     April 7, 1946                  Iowa State University

2  Kareem Abdul-Jabbar        1970      1989        C    7-2   225.0    April 16, 1947  University of California, Los Angeles

3   Mahmoud Abdul-Rauf        1991      2001        G    6-1   162.0     March 9, 1969             Louisiana State University

4    Tariq Abdul-Wahad        1998      2003        F    6-6   223.0  November 3, 1974              San Jose State University


(4550, 8)


<class 'pandas.core.frame.DataFrame'>

RangeIndex: 4550 entries, 0 to 4549

Data columns (total 8 columns):

 #   Column      Non-Null Count  Dtype  

---  ------      --------------  -----  

 0   name        4550 non-null   object 

 1   year_start  4550 non-null   int64  

 2   year_end    4550 non-null   int64  

 3   position    4549 non-null   object 

 4   height      4549 non-null   object 

 5   weight      4544 non-null   float64

 6   birth_date  4519 non-null   object 

 7   college     4248 non-null   object 

dtypes: float64(1), int64(2), object(5)


データは4550件、birth_dateやweightに欠損値が散見されます。


print(df[df['weight'].isnull()])
print()
print(df[df['birth_date'].isnull()].sort_values('year_end', ascending=False))

df2 = df.dropna(how="any")
欠損値データを確認すると昔の人ばかりなので、昔の年代を分析しない場合は削除して構わないでしょう。dropna(how="any")で欠損値を取り除いたデータフレームにします。


# 1foot = 30.48, 1inch = 2.54cm
FOOT= 30.48
INCH = 2.54

# 1pond = 0.4536kg
LB = 0.4536

# フィートをセンチに
def toCenti(height):

    ft, inc = height.split("-")
    cent = int(ft) * FOOT + int(inc) * INCH

    return round(cent, 2)


# ポンドをキログラムに
def toKilogram(weight):

    kg = weight * LB
    
    return round(kg, 2)
    
 
# 以上の関数を身長体重データに適用させる
df2['height'] = df2['height'].apply(toCenti)
df2['weight'] = df2['weight'].apply(toKilogram)


print(df2.head())
print()
print(df2.shape)



                  name  year_start  year_end position  height  weight        birth_date                                college
0       Alaa Abdelnaby        1991      1995      F-C  208.28  108.86     June 24, 1968                        Duke University
1      Zaid Abdul-Aziz        1969      1978      C-F  205.74  106.60     April 7, 1946                  Iowa State University
2  Kareem Abdul-Jabbar        1970      1989        C  218.44  102.06    April 16, 1947  University of California, Los Angeles
3   Mahmoud Abdul-Rauf        1991      2001        G  185.42   73.48     March 9, 1969             Louisiana State University
4    Tariq Abdul-Wahad        1998      2003        F  198.12  101.15  November 3, 1974              San Jose State University

(4213, 8)

変換できました。

player_data_a.csv
完成データは 

2022年6月11日土曜日

matplotlibで一次関数グラフを作る

前回、matplotlibで方眼紙の様な正方形グリッドが作れたら、数学の関数グラフも容易に作れます。

matplotlibはデータをプロットするライブラリなので式をそのままグラフにするのはひと工夫必要です。

今度はオブジェクト指向で関数グラフを作り、一次関数をプロットします。


# オブジェクト指向でグラフ作成
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
 
# これで正方形になります。
ax.set_aspect('equal', adjustable='box')

# 表示する幅
ax.set_xlim(-10, 11)
ax.set_ylim(-10, 11)

# グラフの刻み
ax.set_xticks(np.arange(-10, 10, 5))
ax.set_yticks(np.arange(-10, 10, 5))
 
# 補助線をonにします
ax.minorticks_on() 

# グリッドの主線と補助線
ax.grid(which="major", color="black", alpha=0.5)
ax.grid(which="minor", color="gray", linestyle="--", alpha=0.5)

# 数値表示を0に合わせます。
ax.spines['bottom'].set_position("zero")
ax.spines['left'].set_position("zero")
 

今回はオブジェクト指向のプロットなので若干書き方が違います。特に正方形にするには set_aspect('equal', adjustable='box')という指定をします。 またグラフの数値を0に合わせるため、spines.set_position 関数で zero を指定します。

関数グラフの方眼紙が出来たら、後は一次関数のデータを生成する関数を作ればいいだけ。

# 一次関数のデータを作る関数 
def linear(a, b, ran=np.arange(-10,10)):

    arr = []
    for x in ran:
        y = x*a + b
        arr.append(y)

	# 式から配列データを返します。
    return arr
これを応用すれば二次関数や他の関数もプロットできますね。


[完成形]
#! /usr/bin/env python

# -*- coding:utf-8 -*-
 
 
import numpy as np
import matplotlib.pyplot as plt


# 一次関数のデータを作る関数 
def linear(a, b, ran=np.arange(-10,10)):

    arr = []
    for x in ran:
        y = x*a + b
        arr.append(y)

	# 式から配列データを返します。
    return arr

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
 
# これで正方形になります。
ax.set_aspect('equal', adjustable='box')

# 表示する幅
ax.set_xlim(-10, 11)
ax.set_ylim(-10, 11)

# グラフの刻み
ax.set_xticks(np.arange(-10, 10, 5))
ax.set_yticks(np.arange(-10, 10, 5))
 
# 補助線をonにします
ax.minorticks_on() 

# グリッドの主線と補助線
ax.grid(which="major", color="black", alpha=0.5)
ax.grid(which="minor", color="gray", linestyle="--", alpha=0.5)

# 数値表示を0に合わせます。
ax.spines['bottom'].set_position("zero")
ax.spines['left'].set_position("zero")

x = np.arange(-10, 10)

# y = 2x + 3の一次関数を生成
y = linear(2, 3, x)
ax.plot(x, y)


plt.show()

2022年6月9日木曜日

matplotlibで方眼紙のようなグリッドを作る

Pythonのmatplotlibはグラフ描画のためのライブラリですが、描画はデータによって自動的に調整されるので、時には方眼紙のように正確なグリッドが欲しい場合もあります。

正方形の方眼紙のようなグリッドは、plt.axis("square")で正方形に、ticksでマス目を刻みます。

#! /usr/bin/env python

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

import numpy as np
import matplotlib.pyplot as plt

# 正方形で表示
plt.axis("square")

# 表示範囲の指定
plt.xlim(-10, 10)
plt.ylim(-10, 10)

# 値の刻み
plt.xticks(np.arange(-10, 11, 5))
plt.yticks(np.arange(-10, 11, 5))

#grid マイナー線の指定をします
plt.minorticks_on()
plt.grid()
# マイナー線は破線で透明度50%
plt.grid(which="minor", color="gray", linestyle="--", alpha=0.5)

plt.show()
 
 
ポイントはaxis("square")です。これで数値通りの大きさで表示されます。
あとはxlimでX軸の、ylimでY軸のグラフの範囲、ticksで表示するメモリ数値の刻みを指定します。
グリッドの線はgrid関数で指定しますが、主線だけでなく副線も表示したい場合はminorticks_on関数を呼び出して表示します。
副線は同じgrid関数でwhich="minor"で呼び出します。
あとは"--"で破線、alphaで透明度など指定して好みの方眼紙に調整してください。



以上のようなグラフになります。