Pandas Groupby 加重平均
この記事では、Pandas DataFrame の加重平均を計算する方法を学習します。 また、Pandas DataFrame の加重平均をグループ化する方法についても説明します。
Pandas DataFrame の加重平均を計算する
pandas を pd
としてインポートした後、単純な DataFrame を作成します。 あなたが教師で、生徒の成績を評価しているとしましょう。
全体として、Quiz_1
、Quiz_2
、および Quiz_3
の 3つの異なる評価があります。
コード例:
import pandas as pd
import numpy as np
Student_DF = pd.DataFrame(
{
"Student_Score": [30, 60, 90],
"Std_score_Weight": [1, 2, 3],
"Student_Assessment": ["Quiz_1", "Quiz_2", "Quiz_3"],
}
)
Student_DF
出力:
Student_Score Std_score_Weight Student_Assessment
0 30 1 Quiz_1
1 60 2 Quiz_2
2 90 3 Quiz_3
コード例:
Student_Average = Student_DF["Student_Score"].mean()
Student_Average
出力:
60.0
これらの評価は、体重に応じて全体的なスコアに異なる影響を与えるはずです。 したがって、標本平均ではなく加重平均を計算する必要があります。
まず、Student_Score
に値を掛けてから、結果を重みの合計で割る必要があります。これは、Pandas で実装する方法でもあります。
Pandas ライブラリではベクトル化された計算を実行できるため、Student_Score
に重みを掛けて合計を計算できます。 次に、結果を重みの合計で割る必要があります。
コード例:
Std_weighted_avg = (
Student_DF["Student_Score"] * Student_DF["Std_score_Weight"]
).sum() / Student_DF["Std_score_Weight"].sum()
Std_weighted_avg
この DataFrame の場合、加重平均は次のようになります。
70.0
Groupby
関数を使用して、Pandas で加重平均をグループ化する
次の例では、さまざまな生徒用に別の列を追加しました。 だから、ここに学生 John
と Jack
がいます。
Student_DF = pd.DataFrame(
{
"Student_Score": [30, 50, 90, 40, 50, 20],
"Std_score_Weight": [1, 2, 3, 1, 2, 3],
"Two_Students": ["John", "John", "John", "Jack", "Jack", "Jack"],
"Students_Assessment": [
"Quiz_1",
"Quiz_2",
"Quiz_3",
"Quiz_1",
"Quiz_2",
"Quiz_3",
],
}
)
Student_DF
出力:
Student_Score Std_score_Weight Two_Students Students_Assessment
0 30 1 John Quiz_1
1 50 2 John Quiz_2
2 90 3 John Quiz_3
3 40 1 Jack Quiz_1
4 50 2 Jack Quiz_2
5 20 3 Jack Quiz_3
生徒 Jack
だけの加重平均を計算したいとしましょう。 その場合、ここで query()
メソッドで行ったように、データをフィルタリングできます。
フィルタリングされた DataFrame は次のようになります。
Filtered_by_Jack = Student_DF.query("Two_Students == 'Jack'")
Filtered_by_Jack
出力:
Student_Score Std_score_Weight Two_Students Students_Assessment
3 40 1 Jack Quiz_1
4 50 2 Jack Quiz_2
5 20 3 Jack Quiz_3
これで、以前と同じ計算を適用できますが、今回はフィルタリングされた DataFrame に適用されます。
Std_weighted_avg = (
Filtered_by_Jack["Student_Score"] * Filtered_by_Jack["Std_score_Weight"]
).sum() / Filtered_by_Jack["Std_score_Weight"].sum()
Std_weighted_avg
出力:
33.333333333333336
ただし、この方法は、特に大規模なデータセットを扱う場合は面倒です。 たとえば、学生が 100 人いて、各学生の加重平均を計算するとします。
この例では、データセットにもう 1 人の生徒を追加しました。
Student_DF = pd.DataFrame(
{
"Student_Score": [20, 40, 90, 80, 60, 10, 5, 60, 90],
"Std_score_Weight": [1, 2, 3, 1, 2, 3, 1, 2, 3],
"Three_Student": [
"John",
"John",
"John",
"Jack",
"Jack",
"Jack",
"Harry",
"Harry",
"Harry",
],
"Students_Assessment": [
"Quiz_1",
"Quiz_2",
"Quiz_3",
"Quiz_1",
"Quiz_2",
"Quiz_3",
"Quiz_1",
"Quiz_2",
"Quiz_3",
],
}
)
Student_DF
出力:
Student_Score Std_score_Weight Three_Student Students_Assessment
0 20 1 John Quiz_1
1 40 2 John Quiz_2
2 90 3 John Quiz_3
3 80 1 Jack Quiz_1
4 60 2 Jack Quiz_2
5 10 3 Jack Quiz_3
6 5 1 Harry Quiz_1
7 60 2 Harry Quiz_2
8 90 3 Harry Quiz_3
ただし、次の方法は、データセットに含まれる可能性のある多くの学生に関係なく機能します。 今回は、Groupby_weighted_avg()
という小さなヘルパー関数を作成します。
この関数は、values
、weighted_value
、および加重平均をグループ化する Group_Cols
という列名の 3つのパラメーターを取ります。 計算方法は以前と非常に似ています。 唯一の違いは、それを groupby()
メソッドと組み合わせていることです。
def Groupby_weighted_avg(values, weighted_value, Group_Cols):
return (values * weighted_value).groupby(Group_Cols).sum() / weighted_value.groupby(
Group_Cols
).sum()
Groupby_weighted_avg()
関数を配置すると、この例では Student_Score
と Std_score_Weight
の値を渡すことができます。 Three_Student
で結果をグループ化します。
Groupby_weighted_avg(
Student_DF["Student_Score"],
Student_DF["Std_score_Weight"],
Student_DF["Three_Student"],
)
上記の行を実行すると、各学生の加重平均を含む新しい DataFrame が作成されます。
Three_Student
Harry 65.833333
Jack 38.333333
John 61.666667
dtype: float64
完全なソース コード:
# In[1]:
import pandas as pd
import numpy as np
Student_DF = pd.DataFrame(
{
"Student_Score": [30, 60, 90],
"Std_score_Weight": [1, 2, 3],
"Student_Assessment": ["Quiz_1", "Quiz_2", "Quiz_3"],
}
)
Student_DF
# In[2]:
Student_Average = Student_DF["Student_Score"].mean()
Student_Average
# In[3]:
Std_weighted_avg = (
Student_DF["Student_Score"] * Student_DF["Std_score_Weight"]
).sum() / Student_DF["Std_score_Weight"].sum()
Std_weighted_avg
# In[4]:
# groupby
Student_DF = pd.DataFrame(
{
"Student_Score": [30, 50, 90, 40, 50, 20],
"Std_score_Weight": [1, 2, 3, 1, 2, 3],
"Two_Students": ["John", "John", "John", "Jack", "Jack", "Jack"],
"Students_Assessment": [
"Quiz_1",
"Quiz_2",
"Quiz_3",
"Quiz_1",
"Quiz_2",
"Quiz_3",
],
}
)
Student_DF
# In[5]:
Filtered_by_Jack = Student_DF.query("Two_Students == 'Jack'")
Filtered_by_Jack
# In[6]:
Std_weighted_avg = (
Filtered_by_Jack["Student_Score"] * Filtered_by_Jack["Std_score_Weight"]
).sum() / Filtered_by_Jack["Std_score_Weight"].sum()
Std_weighted_avg
# In[7]:
Student_DF = pd.DataFrame(
{
"Student_Score": [20, 40, 90, 80, 60, 10, 5, 60, 90],
"Std_score_Weight": [1, 2, 3, 1, 2, 3, 1, 2, 3],
"Three_Student": [
"John",
"John",
"John",
"Jack",
"Jack",
"Jack",
"Harry",
"Harry",
"Harry",
],
"Students_Assessment": [
"Quiz_1",
"Quiz_2",
"Quiz_3",
"Quiz_1",
"Quiz_2",
"Quiz_3",
"Quiz_1",
"Quiz_2",
"Quiz_3",
],
}
)
Student_DF
# In[8]:
def Groupby_weighted_avg(values, weighted_value, Group_Cols):
return (values * weighted_value).groupby(Group_Cols).sum() / weighted_value.groupby(
Group_Cols
).sum()
# In[9]:
Groupby_weighted_avg(
Student_DF["Student_Score"],
Student_DF["Std_score_Weight"],
Student_DF["Three_Student"],
)
Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.
LinkedIn