Есть ли способ умножить значения в двух столбцах при группировке по значениям в третьем столбце с использованием pandas?

#python #pandas

#python #pandas

Вопрос:

Поэтому я стараюсь избегать использования цикла при вычислении среднего значения взвешенных оценок в каждом из этих курсов.

Я просто не могу понять, что делать. Я предполагаю, что могу использовать groupby и выполнить соответствующие вычисления?

Это фрейм данных:

 data = 

mark  weight  course_id
78      10          1
87      40          1
15      50          1
78      90          3
40      10          3
 

Это желаемый результат:

 result=

course_id  course_average
1            50.1
3            74.2      

 

Ответ №1:

Если числа не всегда складываются до 100 для каждой группы, то вы можете рассчитать пропорцию weight для каждой строки каждой группы и умножить на mark .

 (data.assign(wa = data['mark'] * data['weight'] / 
             data.groupby('course_id')['weight'].transform('sum'))
     .groupby('course_id')['wa'].sum())
Out[1]: 
course_id
1    50.1
3    74.2
Name: wa, dtype: float64
 

Если веса составляют до 100 для каждой группы, тогда вычисление упрощается:

 data.assign(wa = data['mark'] * data['weight'] / 100).groupby('course_id')['wa'].sum()

Out[2]: 
course_id
1    50.1
3    74.2
Name: wa, dtype: float64
 

Комментарии:

1. Да, я забыл упомянуть, что данные гарантированно складываются до 100.

Ответ №2:

Это один из способов сделать это :

 (df.assign(course_average=df.mark * df.weight)
   .groupby("course_id")
   .pipe(lambda x: x.course_average.sum().div(x.weight.sum()))
   .reset_index(name="course_average"))


    course_id   course_average
0      1         50.1
1      3         74.2
 

Ответ №3:

Вы можете сделать это с помощью простой строки 1, используя groupby и lambda для средневзвешенного значения следующим образом —

 df.groupby(['course_id']).apply(lambda x: sum(x['mark']*x['weight'])/sum(x['weight']))
 
 course_id
1    50.1
3    74.2
dtype: float64
 

Комментарии:

1. Было бы более эффективно избегать apply и использовать assign, как это делал Дэвид Эриксон? Я думаю, что оба решения здесь в любом случае создадут новый фрейм данных в памяти.