Pandas Groupby 加重平均

Salman Mehmood 2023年6月21日
  1. Pandas DataFrame の加重平均を計算する
  2. Groupby 関数を使用して、Pandas で加重平均をグループ化する
Pandas Groupby 加重平均

この記事では、Pandas DataFrame の加重平均を計算する方法を学習します。 また、Pandas DataFrame の加重平均をグループ化する方法についても説明します。

Pandas DataFrame の加重平均を計算する

pandas を pd としてインポートした後、単純な DataFrame を作成します。 あなたが教師で、生徒の成績を評価しているとしましょう。

全体として、Quiz_1Quiz_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 で加重平均をグループ化する

次の例では、さまざまな生徒用に別の列を追加しました。 だから、ここに学生 JohnJack がいます。

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() という小さなヘルパー関数を作成します。

この関数は、valuesweighted_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_ScoreStd_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"],
)
著者: Salman Mehmood
Salman Mehmood avatar Salman Mehmood avatar

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

関連記事 - Pandas Groupby