Как обрабатывать мультигруппу Postgres 9.5 в Pandas

Поняв, как именно работает группировка наборов, мы увидим, как написать функцию Python для этого, используя Pandas.

SQL: набор группировок

Супер полезная мультигруппировка Postgres 9.5. Это создает союз различных группировок. Давайте создадим таблицу для нашего примера:

— create a table
CREATE TABLE students (
 name Text Not null,
 class TEXT NOT NULL,
 gender TEXT NOT NULL,
 grade INTEGER NOT NULL
 
);
 — insert some values
INSERT INTO students VALUES ( 'Pierre',1,1,15);
INSERT INTO students VALUES ( 'Paul',2,1,15);
INSERT INTO students VALUES ( 'Jack',1,1,14);
INSERT INTO students VALUES ( 'Marie',1,2,12);
INSERT INTO students VALUES ( 'Lea',2,2,18);
INSERT INTO students VALUES ( 'Nath',2,2,10);

Цель: рассчитать среднее значение по классу и по полу.

Если мы хотим рассчитать в одной и той же таблице средние оценки по классам и полу, мы могли бы рассчитать среднее значение по классам в одной таблице, среднее значение по полу в другой, а затем соединить их по вертикали. Именно в этом цель группирующего набора Postgres:

— fetch some values
SELECT class,gender,AVG(grade) 
FROM students 
GROUP BY GROUPING SETS (class,gender);

Попробуйте эти запросы здесь: https://extendsclass.com/postgresql-online.html

В пандах

import pandas as pd
df= pd.DataFrame(
{'name':['Pierre','Paul','Jack','Marie','Lea','Nath']   ,
'class': ['Class 1','Class 2','Class 1','Class 1','Class 2','Class 2'] ,
'gender': ['M','M','M','F','F','F'] ,
'grade':  [15,15,14,12,18,10]})

Нам нужно создать две группы, а затем присоединиться к ним. Мы могли бы использовать базовую функцию groupby.

df_temp=df.groupby(by='class').mean().reset_index()

Почему это не работает? потому что он также вычислит среднее значение () пола столбца, которое является числовым значением.

Так как мы хотим продолжать по тому же пути, мы можем вычислить это так, но тогда, отбрасываем ненужный нам столбец, вот он пол

df_temp.drop(columns='gender')

Как поместить все в функцию?

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

def group_set(df,list_groupset):
    
    #initialzation for the Concatenation
    data=pd.DataFrame()
    for group in list_groupset :
        
        #Group by on one of the list
        df_temp=df.groupby(by=group).mean().reset_index()
    
        #Which column do we need to delete ?
        list_groupset_temp=list(list_groupset)
        list_groupset_temp.remove(group)
        df_temp=df_temp.drop(columns=list_groupset_temp)
        
        #Merging the different group by 
        data=pd.concat([data,df_temp])
        
    return(data)
list_groupset = ['class','gender']
group_set(df,list_groupset)

Если вам понравилась эта история, вы можете проверить мой последний пост здесь: