質問
Pythonでデータ分析をしている初学者です。
5人の生徒の5つのテスト結果が格納されたデータフレームがあります。
テストの結果から、特定の生徒の成績が表示されたRadarChartを作成したいと考えております。
その前段階で、5人の5つのテスト結果を正規化し、変数化したものをリストに格納し
その後のRadarChartを作成する関数の中で参照するという形をとっています。
前段階の部分、指定の生徒のテスト結果を各テストごとに正規化しているため、同じような文脈が5つあるのですが、
どのようにすればここの部分、簡素化するでしょうか?
「案1」のようにfor分で回してみると、正規化されたスコアが5つしっかりと出てきますが、変数が固定されてしまうため、グラフ作成前のvalues = [s1_p, s2_p, s3_p, s4_p, s5_p]の中に同じように格納できません。
変数もfor分で回した分だけ作成できれば良いのですが…。
何か良い案、どうかご教授の程よろしくお願いいたします。
該当のソースコード
Python
1def radar(student): 2 import pandas as pd 3 import numpy as np 4 import matplotlib.pyplot as plt 5 import japanize_matplotlib 6 from sklearn import preprocessing 7 8 df = pd.DataFrame({ 9 "Students":["Takahashi","Aoki","Yamada","Nakamura","Ogawa"], 10 "Score1":[30,40,50,55,20], 11 "Score2":[10,50,60,60,25], 12 "Score3":[35,40,20,30,25], 13 "Score4":[60,50,20,35,35], 14 "Score5":[45,40,40,35,50] 15 }) 16 17 df = df.set_index("Students") 18 19 ## Score1 20 # transpose 21 s1 = df["Score1"].values[:,None] 22 # Maxを10に変更 23 mm = preprocessing.MinMaxScaler(feature_range=(0, 10)) 24 # 正規化 25 s1_nor = mm.fit_transform(s1) 26 # 元の pandas.Series 型インスタンスに戻す 27 s1_s = pd.Series(s1_nor[:,0], index=df["Score1"].index) 28 # Select student 29 s1_p = s1_s[f"{student}"] 30 31 ## Score2 32 s2 = df["Score2"].values[:,None] 33 s2_nor = mm.fit_transform(s2) 34 s2_s = pd.Series(s2_nor[:,0],index=df["Score2"].index) 35 s2_p = s2_s[f"{student}"] 36 37 ## Score3 38 s3 = df["Score3"].values[:,None] 39 s3_nor = mm.fit_transform(s3) 40 s3_s = pd.Series(s3_nor[:,0],index=df["Score3"].index) 41 s3_p = s3_s[f"{student}"] 42 43 ## Score4 44 s4 = df["Score4"].values[:,None] 45 s4_nor = mm.fit_transform(s4) 46 s4_s = pd.Series(s4_nor[:,0],index=df["Score4"].index) 47 s4_p = s4_s[f"{student}"] 48 49 ## Score5 50 s5 = df["Score5"].values[:,None] 51 s5_nor = mm.fit_transform(s5) 52 s5_s = pd.Series(s5_nor[:,0],index=df["Score5"].index) 53 s5_p = s5_s[f"{student}"] 54 55 labels = ["Score1","Score2","Score3", "Score4","Score5"] 56 values = [s1_p, s2_p, s3_p, s4_p, s5_p] 57 58 def plot_polar(labels, values, imgname): 59 angles = np.linspace(0, 2 * np.pi, len(labels) + 1, endpoint=True) 60 values = np.concatenate((values, [values[0]])) # 閉じた多角形にする 61 fig = plt.figure(figsize=(8,8), facecolor="White") 62 ax = fig.add_subplot(1,1,1,polar=True) 63 ax.plot(angles, values, 'o-',color="limegreen") # 外枠 64 ax.fill(angles, values, alpha=0.25,color="limegreen") # 塗りつぶし 65 ax.set_thetagrids(angles[:-1] * 180 / np.pi, labels,fontsize=14) # 軸ラベル 66 ax.set_title(f"{student}",fontsize=15) # グラフタイトル 67 ax.set_rgrids([]) # 円形の目盛線を消す 68 ax.spines['polar'].set_visible(False) # 一番外側の円を消す 69 ax.set_theta_zero_location("N") # 始点を上(北)に変更 70 ax.set_theta_direction(-1) # 時計回りに変更(デフォルトの逆回り) 71 rgrids = [0, 2, 4, 6, 8, 10] # メモリ軸の生成 72 for grid_value in rgrids: # 多角形の目盛線を引く 73 grid_values = [grid_value] * (len(labels)+1) 74 ax.plot(angles, grid_values, color="gray", linewidth=0.5) 75 for t in rgrids: # メモリの値を表示する 76 ax.text(x=0, y=t, s=t) # xが偏角、yが絶対値でテキストの表示場所が指定される 77 ax.set_rlim(0, 10) # rの範囲を指定 78 fig.subplots_adjust(bottom=0.05) # グラフ位置を下方に移動 79 80 return plot_polar(labels, values, f"radar_{student}.png") 81 82radar("Takahashi")
案1
Python
1def radar(student): 2 for value in Scores: 3 # transpose 4 set = df[value].values[:,None] 5 # Maxを10に変更 6 mm = preprocessing.MinMaxScaler(feature_range=(0, 10)) 7 # 正規化 8 set_nor = mm.fit_transform(set) 9 # 元の pandas.Series 型インスタンスに戻す 10 set_s = pd.Series(set_nor[:,0], index=df[value].index) 11 # Select Student 12 set_p = set_s[f"{student}"] 13 print(set_p) 14radar("Takahashi")
案1結果
2.8571428571428577 0.0 7.5 10.0 6.666666666666668
補足情報(FW/ツールのバージョンなど)
python3.9、VSCode
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2022/05/11 05:28