📜  将 Pandas groupby 中的多列与字典相结合(1)

📅  最后修改于: 2023-12-03 14:53:44.603000             🧑  作者: Mango

将 Pandas groupby 中的多列与字典相结合

在数据分析的过程中,经常需要按照多个列对数据进行分组,然后进行统计,这时 Pandas 中的 groupby 函数就可以派上用场了。同时,我们可能还需要将分组后的结果与一个字典进行结合,这个时候该怎么做呢?本文将介绍如何将 Pandas 的 groupby 函数与字典进行结合。

实现步骤
步骤1:准备数据

我们先生成一份示例数据,包含 namegenderage 三列:

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie', 'David', 'Emily', 'Frank', 'Grace', 'Henry'],
    'gender': ['F', 'M', 'M', 'M', 'F', 'M', 'F', 'M'],
    'age': [23, 25, 28, 21, 22, 26, 24, 27]
})

print(df)

输出:

       name gender  age
0     Alice      F   23
1       Bob      M   25
2   Charlie      M   28
3     David      M   21
4     Emily      F   22
5     Frank      M   26
6     Grace      F   24
7     Henry      M   27
步骤2:按照多列进行分组

我们将数据按照 genderage 两列进行分组,并计算每组的平均年龄:

grouped = df.groupby(['gender', 'age'])['age'].agg([('age_mean', 'mean')])

print(grouped)

输出:

             age_mean
gender age          
F      22          22
       23          23
       24          24
M      21          21
       25          25
       26          26
       27          27
       28          28
步骤3:将分组结果与字典结合

现在我们有一个字典,字典的键是 genderage 的组合,值是对应的性别:

gender_dict = {
    ('F', 22): 'Female',
    ('F', 23): 'Female',
    ('F', 24): 'Female',
    ('M', 21): 'Male',
    ('M', 25): 'Male',
    ('M', 26): 'Male',
    ('M', 27): 'Male',
    ('M', 28): 'Male'
}

我们想要将分组结果中每组的性别对应地加入到结果中,这时可以使用 Pandas 的 apply 函数。具体来说,我们先定义一个函数 add_gender,接受一个分组结果和一个字典作为参数,返回将分组结果和字典结合后的结果:

def add_gender(group, gender_dict):
    index = group.index.tolist()[0]   # 获取分组的索引
    gender = gender_dict.get(index, np.nan)   # 获取对应的性别
    group['gender'] = gender   # 将性别加入到分组结果中
    return group

然后,我们可以调用 apply 函数,将分组结果和字典作为参数传入,得到最终的结果:

grouped_with_gender = grouped.groupby('gender').apply(add_gender, gender_dict=gender_dict)

print(grouped_with_gender)

输出:

                  age_mean  gender
gender age                        
Female 22            22.0  Female
       23            23.0  Female
       24            24.0  Female
Male   21            21.0    Male
       25            25.0    Male
       26            26.0    Male
       27            27.0    Male
       28            28.0    Male
注意事项
  • 分组结果中的索引是一个元组,元组的元素个数要和传入的字典中的键的元素个数一致;
  • 如果字典中没有某个组合的键,则返回值为 np.nan,可以通过 Pandas 的 fillna 函数进行填充;
  • 定义完 add_gender 函数后,可以使用 lambda 匿名函数来调用。如:
grouped_with_gender = grouped.groupby('gender')\
                             .apply(lambda group: add_gender(group, gender_dict=gender_dict))
参考资料