前提・実現したいこと
プロ野球選手のデータをスクレイピングしたいです。
数日間ググりながらエラーと格闘してコードを修正して見たのですが、全く答えが見つからず
こちらでどなたか助けていただけないかと藁をもすがる思いで書き込ませて頂きました。
下記のページ通りにやってみたのですが、途中でエラーが発生して出来ません。
https://qiita.com/kjybinp1105/items/eeca54b725c27890aa4f
※過去の記事なので、URLだけ2019年のものにアップデートしています。
①urlをリスト形式で取得
②URLを入力:2017年だけ命名規則が違う
③データをURLから取得
④選手IDの作成
は、それぞれやると違和感のあるアウトプットはあるものの、エラーは出ずに動作しました(試したことに違和感は記載しました。)
⑤選手IDの付与
で下記のエラーが出てしまい、色々とトライしてもコードを動作させることが出来ませんでした。
発生している問題・エラーメッセージ
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-60-c862335b2217> in <module> 38 df_all[i]['ID'] = -1 39 for j in range(len(df_all[i])): ---> 40 df_all[i].loc[j,'ID'] = dic[df_all[i].loc[j,'選手名']] 41 df_all[i].index = df_all[i]['ID'] 42 df_all[i] = df_all[i].drop('ID',axis=1) ~/anaconda3/lib/python3.7/site-packages/pandas/core/generic.py in __hash__(self) 1814 def __hash__(self): 1815 raise TypeError('{0!r} objects are mutable, thus they cannot be' -> 1816 ' hashed'.format(self.__class__.__name__)) 1817 1818 def __iter__(self): TypeError: 'Series' objects are mutable, thus they cannot be hashed
該当のソースコード
Python
1import numpy 2import pandas as pd 3import matplotlib.pylab as plt 4 5#①urlをリスト形式で取得 6df_all = []//各要素に各年のデータが入る 7years = range(19,8,-1) 8urls = [] 9 10#②URLを入力:2019年だけ命名規則が違う 11for year in years: 12 if(year==19): 13 urls.append('http://baseball-data.com/stats/pitcher-all/era-1.html') 14 else: 15 urls.append('http://baseball-data.com/'+ "{0:02d}".format(year)+'/stats/pitcher-all/era-1.html') 16 17#③データをURLから取得 18for url in urls: 19 print('取得URL:'+url) 20 df = pd.io.html.read_html(url) 21 df = df[0] 22 df_all.append(df) 23 24#④選手IDの作成 25name_list = [] 26dic = {} 27for i in range(len(df_all)): 28 name_list.extend(df_all[i]['選手名']) 29name_list = list(set(name_list)) 30for i,name in enumerate(name_list): 31 dic[name] = i 32 33#⑤選手IDの付与 34for i in range(len(df_all)): 35 df_all[i]['ID'] = -1 36 for j in range(len(df_all[i])): 37 df_all[i].loc[j,'ID'] = dic[df_all[i].loc[j,'選手名']] 38 df_all[i].index = df_all[i]['ID'] 39 df_all[i] = df_all[i].drop('ID',axis=1) 40 41#⑥index被りを除去 42for i in range(len(df_all)): 43 doubled_index = [] 44 count = df_all[i].index.value_counts() 45 for j in count.index: 46 if(count.loc[j]>1): 47 doubled_index.append(j) 48 df_all[i] = df_all[i].drop(doubled_index) 49 50#⑦カラム名に年を付ける 51for i in range(len(df_all)): 52 for col_name in df_all[i].columns: 53 df_all[i] = df_all[i].rename(columns = {col_name:col_name+"20"+"{0:02d}".format(years[i])}) 54 55df_m = pd.concat(df_all,axis=1)
試したこと
それぞれのステップを順番に動かしたところ①から③は問題なくすることが出来ました。
③の後にdfの中身を見るとなぜか見出しが二重だったところは気になりました。
④はname_listの中身を見ると、なぜか中身が具体的な選手名ではなく'選手名'という値しか入っていなかったです。
補足情報(FW/ツールのバージョンなど)
最新のJupyter Notebookでやっています。
回答1件
あなたの回答
tips
プレビュー