【Python】プロ野球データをpandasでいじってみる


##Excelファイルの読み込み
スクレイピングしてExcel形式にしていたデータをpandasでいじってみた
拡張子がxlsmでも、xlsと同様に読み込みできる

~~~python
import pandas as pd

df= pd.read_excel('日本プロ野球野手2018.xlsm', sheet_name='シート')
~~~

##指定列のデータを抽出
#### カラム名の確認

~~~python
print(df.columns) 
~~~
Index([ 'No',     pos, 'チーム',  '年度', '選手名',  '試合',  '打席',  '打数',  '得点',  '安打','二塁',  '三塁',  '本塁',  '塁打',  '打点',  '盗塁',  '盗刺',  ～（以下略）
#### 特定な列のデータだけを抽出

~~~python
df1=df[['No','チーム','年度','選手名','試合','本塁','盗塁','打率']]
print(df1.head(5))
~~~
   No チーム    年度    選手名   試合  本塁  盗塁     打率
0 NaN  横浜  2018  宮崎　敏郎  142  28   0  0.318
1 NaN  横浜  2018  筒香　嘉智  139  38   0  0.295
2 NaN  横浜  2018   N.ソト  107  41   0   0.31
3 NaN  横浜  2018  J.ロペス  110  26   0  0.288
4 NaN  横浜  2018     大和  113   2  10  0.244

##インデックスとは別の行に連番を振る
**連番を生成して、そのまま、連番列に代入しても動作はするが、Warningが発生する**

~~~python
serial_num = pd.RangeIndex(start=1, stop=len(df1.index) + 1, step=1)
df1['No'] = serial_num
print(df1.head(5))
~~~

SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  df1['No'] = serial_num

**下記のように、記述するとWarningはでなくなった**

~~~python
serial_num = pd.RangeIndex(start=1, stop=len(df1.index) + 1, step=1)
df1.loc[:,'No']=serial_num
print(df1.head(5))
~~~
   No チーム    年度    選手名   試合  本塁  盗塁     打率
0   1  横浜  2018  宮崎　敏郎  142  28   0  0.318
1   2  横浜  2018  筒香　嘉智  139  38   0  0.295
2   3  横浜  2018   N.ソト  107  41   0   0.31
3   4  横浜  2018  J.ロペス  110  26   0  0.288
4   5  横浜  2018     大和  113   2  10  0.244

##不要行の削除

~~~python
#チームの区切りにもヘッダと同じものが出てきて、後から数値処理に支障が出るので、行削除する
df1=df1[(df1['試合'] !='試合')]
df1=df1[(df1['選手名'] !='選手名')]

#年度列のチーム計行削も除する
df1=df1[(df1['年度'] !='チーム計')]

#打率がないものを、便宜上0に置き換える
df1=df1.replace('-', '0')
~~~

##数値データへの変換
そのままだと、数値もobject型になっているので数値列は数値型に変換

~~~python
print(df2.dtypes)
~~~
No      int64
チーム    object
年度     object
選手名    object
試合     object
本塁     object
盗塁     object
打率     object
dtype: object

~~~python
df1.loc[:,'年度']=df1['年度'].astype(int)
df1.loc[:,'試合']=df1['試合'].astype(int)
df1.loc[:,'本塁']=df1['本塁'].astype(int)
df1.loc[:,'盗塁']=df1['盗塁'].astype(int)
df1.loc[:,'打率']=df1['打率'].astype(float)
print(df1.dtypes)
~~~

No       int64
チーム     object
年度       int32
選手名     object
試合       int32
本塁       int32
盗塁       int32
打率     float64
dtype: object


##データを抽出

~~~python
print(df1[(df1['チーム'] == '巨人') & ((df1['試合']) >=90)])
~~~
      No チーム    年度     選手名   試合  本塁  盗塁     打率
352  353  巨人  2018   岡本　和真  143  33   2  0.309
353  354  巨人  2018   C.マギー  132  21   2  0.285
354  355  巨人  2018   坂本　勇人  109  18   9  0.345
355  356  巨人  2018   亀井　善行  123  13   4  0.254
356  357  巨人  2018   長野　久義  116  13   3  0.290
357  358  巨人  2018   吉川　尚輝   92   4  11  0.253
359  360  巨人  2018   小林　誠司  119   2   0  0.219
361  362  巨人  2018   田中　俊太   99   2   6  0.241
362  363  巨人  2018  阿部　慎之助   95  11   0  0.247
378  379  巨人  2018   吉川　大幾   97   0   7  0.16

~~~python
MaxNo=(df1[(df1['チーム'] == '巨人') ].本塁.idxmax())
print("本塁打　:"+df1.loc[MaxNo,'選手名']+":"+str(df1.loc[MaxNo,'本塁'])+"本") 

MaxNo=(df1[(df1['チーム'] == '巨人') ].盗塁.idxmax())
print("盗塁　:"+df1.loc[MaxNo,'選手名']+":"+str(df1.loc[MaxNo,'盗塁'])+"個")

MaxNo=(df1[(df1['チーム'] == '巨人') & ((df1['試合']) >=80)].打率.idxmax())
print("打率　:"+df1.loc[MaxNo,'選手名']+":"+str(df1.loc[MaxNo,'打率'])) 
~~~
本塁打　:岡本　和真:33本
盗塁　:吉川　尚輝:11個
打率　:坂本　勇人:0.345

##重複行の削除
チームごとに最初の一人を抽出

~~~python
print(df1[~df1.duplicated(subset='チーム')])
~~~

No     チーム    年度    選手名   試合  本塁  盗塁     打率
0   NaN      横浜  2018  宮崎　敏郎  142  28   0  0.318
58  NaN   オリックス  2018  吉田　正尚  143  26   3  0.321
118 NaN      広島  2018  田中　広輔  143  10  32  0.262
174 NaN      中日  2018  大島　洋平  141   7  21  0.274
232 NaN      楽天  2018     銀次  139   5   1  0.276
293 NaN    日本ハム  2018  西川　遥輝  140  10  44  0.278
352 NaN      巨人  2018  岡本　和真  143  33   2  0.309
407 NaN  ソフトバンク  2018  上林　誠知  143  22  13   0.27
464 NaN      西武  2018  秋山　翔吾  143  24  15  0.323
520 NaN     ロッテ  2018  中村　奨吾  143   8  39  0.284
581 NaN    ヤクルト  2018  山田　哲人  140  34  33  0.315
642 NaN      阪神  2018  糸原　健斗  143   1   6  0.286

－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－
###守備位置別試合数リストから、代表的ポジションを抽出

~~~python
#守備位置別試合数リストから、代表的ポジションを抽出
df1=df[["pos",'守備']]
#print(df1.head(5))

position = {'投': '1','捕': '2', '一': '3','二': '4', '三': '5', '遊': '6',
           '右':'7','中': '8', '左': '9', '外': '789','指': 'DH'}
 
for i in range(10):
    df1.loc[i,'pos']=position[df1.loc[i,'守備'][1]]

print(df1.head(5))
~~~
   pos                 守備
0    5   (三)140 (一)3 (指)2
1  789        (外)132 (指)5
2  789  (外)76 (一)33 (二)25
3    3             (一)108
4    6   (遊)109 (二)2 (外)2