Простые вычисления по указанным c строкам в pandas DataFrame - PullRequest
0 голосов
/ 18 июня 2020

Предположим, у меня есть следующие данные:

from pandas import DataFrame

boxes = {'Students': ['Alice','Alice','Alice','Bob','Bob','Red','Red','Red','Red'],
         'Subjects': ['Math','History','Economics','Economics','Math','Sociology','Ethics','History','Economics'],
         'Grade': [100,75,85,95,100,85,75,78,82]
        }

df = DataFrame(boxes, columns= ['Students','Subjects','Grade'])

Я хочу найти среднюю оценку и количество классов, которые прошли каждый из Alice и Red:

Итак мне нужен результат:

          GPA      Count
Students        
Alice     86.67    3
Red       80.00    4

Есть ли встроенные pandas функции, которые это делают? Я понимаю, что следующий код

g = df.groupby('Students')['Grade']
df1 = pd.concat([g.mean().round(2), g.count()], axis=1)
df1.columns = ['GPA', 'Count']

найдет то, что я хочу, для всех студентов, но я хочу иметь возможность найти это для определенных c студентов.

1 Ответ

1 голос
/ 18 июня 2020

Здесь вы можете использовать named aggregation.

df.groupby('Students').agg(GPA = ('Grade','mean'),
                           Count = ('Grade','count'))

                GPA  Count
Students
Alice     86.666667      3
Bob       97.500000      2
Red       80.000000      4

Чтобы получить только значения Alice и Red, создайте маску, используя boolean indexing а затем groupby

mask = df.Students.str.contains(r'\bAlice\b|\bRed\b') 
#or
# mask = (df.Students =='Alice') | (df.Students=='Red')

df[mask].groupby('Students').agg(GPA = ('Grade','mean'),
                           Count = ('Grade','count'))

                GPA  Count
Students
Alice     86.666667      3
Red       80.000000      4

Или, как @jezrael предложил, вы можете использовать здесь pd.Series.isin.

mask = df.Students.isin(['Alice', 'Red'])
df[mask].groupby('Students').agg(GPA = ('Grade','mean'),
                           Count = ('Grade','count'))
  • Timeit результаты для создания булевой маски

    • isin 111 мкс ± 6,67 мкс на л oop (среднее ± стандартное отклонение из 7 прогонов, 10000 циклов в каждом)
    • .str.contains 146 мкс ± 3,75 мкс на л oop (среднее ± стандартное отклонение из 7 прогонов, 10000 циклов в каждом)
      • Подробная информация об используемом регулярном выражении здесь в regex101.
    • boolean mask chaining 261 мкс ± 8,22 мкс на л oop (среднее ± стандартное отклонение из 7 прогонов, по 1000 циклов в каждом)
...