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