详解 Pandas 的 groupby 分组函数

一、groupby 基本使用

import pandas as pd

# 构建dataframe数据
df = pd.DataFrame({
    'name': ['三国演义', '诛仙', '凡人修仙传', '活着', '射雕英雄传', '霸道总裁爱上我', '少年歌行', '少年白马醉春风', '神雕侠侣'],
    'category': ['历史', '修真', '修真', '现实', '武侠', '都市', '仙侠', '仙侠', '武侠'],
    'price': [33.5, 26, 32.8, 29, 37, 25.5, 30.2, 28, 38],
    'num': [2, 1, 3, 6, 4, 8, 5, 3, 2]
})

# 分组操作,使用 by 参数指定分组列
group_df = df.groupby(by="category")
print(group_df) # <pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000022484EE6610>
print(type(group_df)) # <class 'pandas.core.groupby.generic.DataFrameGroupBy'>

# DataFrame 经过分组之后得到 DataFrameGroupBy 对象

二、DataFrameGroupBy 的属性

# 循环打印 DataFrameGroupBy 的内容

for name, group in group_df:
    # name 是所有分组的 key
    print(name)

输出结果

仙侠
修真
历史
武侠
现实
都市
# 循环打印 DataFrameGroupBy 的内容

for name, group in group_df:
    # group 是对应分组 key 的组内 DataFrame
    print(group)

输出结果

      name     category  price  count
6  少年歌行       仙侠   30.2      5
7  少年白马醉春风       仙侠   28.0      3

    name category  price  count
1     诛仙       修真   26.0      1
2  凡人修仙传       修真   32.8      3

   name category  price  count
0  三国演义       历史   33.5      2

    name category  price  count
4  射雕英雄传       武侠   37.0      4
8   神雕侠侣       武侠   38.0      2

  name category  price  count
3   活着       现实   29.0      6

      name category  price  count
5  霸道总裁爱上我       都市   25.5      8

三、groupby 的参数

def groupby(
        self,
        by=None, # 指定分组列,可以指定多列 [col1, col2,...]
        axis: Axis | lib.NoDefault = lib.no_default, # 指定按行分组 0 或按列分组 1,默认 0
        level: IndexLabel | None = None,
        as_index: bool = True, # 返回对象是否以分组名作为索引,默认 True
        sort: bool = True, # 是否对分组名进行排序,默认 True,关闭自动排序可以提高性能
        group_keys: bool = True, # 默认 True,调用apply时,将分组的keys添加到索引中
        observed: bool | lib.NoDefault = lib.no_default,
        dropna: bool = True,
    ) -> DataFrameGroupBy:

四、分组后的聚合操作

1. 简单聚合

import pandas as pd

df = pd.DataFrame({
    'name': ['三国演义', '诛仙', '凡人修仙传', '活着', '射雕英雄传', '霸道总裁爱上我', '少年歌行', '少年白马醉春风', '神雕侠侣'],
    'category': ['历史', '修真', '修真', '现实', '武侠', '都市', '仙侠', '仙侠', '武侠'],
    'price': [33.5, 26, 32.8, 29, 37, 25.5, 30.2, 28, 38],
    'num': [2, 1, 3, 6, 4, 8, 5, 3, 2]
})

group_df = df.groupby(by="category")

# (1)count():统计数量
print(group_df.count())

# (2)sum():求和
print(group_df["price"].sum())

# (3)min()/max():取最小值/最大值
print(group_df["num"].max())
print(group_df["price"].min())

# (4)median():取中位数
print(group_df["price"].median())

# (5)mean():取平均值
print(group_df["num"].mean())

# (6)std():取标准差
print(group_df["price"].std())

# (7)var():取方差
print(group_df["num"].var())

2. agg

import pandas as pd

df = pd.DataFrame({
    'name': ['三国演义', '诛仙', '凡人修仙传', '活着', '射雕英雄传', '霸道总裁爱上我', '少年歌行', '少年白马醉春风', '神雕侠侣'],
    'category': ['历史', '修真', '修真', '现实', '武侠', '都市', '仙侠', '仙侠', '武侠'],
    'price': [33.5, 26, 32.8, 29, 37, 25.5, 30.2, 28, 38],
    'num': [2, 1, 3, 6, 4, 8, 5, 3, 2]
})

group_df = df.groupby(by="category")

# agg:针对不同的字段指定不同的聚合函数
agg_df = group_df.agg({
    "price": ["max", "mean"],
    "num": "sum"
})

print(agg_df)

结果展示

         price       num
           max  mean sum
category                
仙侠        30.2  29.1   8
修真        32.8  29.4   4
历史        33.5  33.5   2
武侠        38.0  37.5   6
现实        29.0  29.0   6
都市        25.5  25.5   8
# 自定义列名
agg_df2 = group_df.agg(
    my_col = ("price", "mean")
)

print(agg_df2)

结果展示

         my_col
category        
仙侠          29.1
修真          29.4
历史          33.5
武侠          37.5
现实          29.0
都市          25.5

3. transform

import pandas as pd

df = pd.DataFrame({
    'name': ['三国演义', '诛仙', '凡人修仙传', '活着', '射雕英雄传', '霸道总裁爱上我', '少年歌行', '少年白马醉春风', '神雕侠侣'],
    'category': ['历史', '修真', '修真', '现实', '武侠', '都市', '仙侠', '仙侠', '武侠'],
    'price': [33.5, 26, 32.8, 29, 37, 25.5, 30.2, 28, 38],
    'num': [2, 1, 3, 6, 4, 8, 5, 3, 2]
})

group_df = df.groupby(by="category")

# transform:会保持每一个分组的形状与原始数据形状相同
trans_df = group_df.transform("sum")
print(trans_df)

结果展示

         name  price  num
0         三国演义   33.5    2
1      诛仙凡人修仙传   58.8    4
2      诛仙凡人修仙传   58.8    4
3           活着   29.0    6
4    射雕英雄传神雕侠侣   75.0    6
5      霸道总裁爱上我   25.5    8
6  少年歌行少年白马醉春风   58.2    8
7  少年歌行少年白马醉春风   58.2    8
8    射雕英雄传神雕侠侣   75.0    6

4. apply

import pandas as pd

df = pd.DataFrame({
    'name': ['三国演义', '诛仙', '凡人修仙传', '活着', '射雕英雄传', '霸道总裁爱上我', '少年歌行', '少年白马醉春风', '神雕侠侣'],
    'category': ['历史', '修真', '修真', '现实', '武侠', '都市', '仙侠', '仙侠', '武侠'],
    'price': [33.5, 26, 32.8, 29, 37, 25.5, 30.2, 28, 38],
    'num': [2, 1, 3, 6, 4, 8, 5, 3, 2]
})

group_df = df.groupby(by="category")

# apply:传入一个 lambda 函数表达式或一个函数作为操作运算
apply_df = group_df.apply(lambda x: x["name"] + "_abc")

print(apply_df)

结果展示

category   
仙侠        6       少年歌行_abc
          7    少年白马醉春风_abc
修真        1         诛仙_abc
          2      凡人修仙传_abc
历史        0       三国演义_abc
武侠        4      射雕英雄传_abc
          8       神雕侠侣_abc
现实        3         活着_abc
都市        5    霸道总裁爱上我_abc

5. filter

import pandas as pd

df = pd.DataFrame({
    'name': ['三国演义', '诛仙', '凡人修仙传', '活着', '射雕英雄传', '霸道总裁爱上我', '少年歌行', '少年白马醉春风', '神雕侠侣'],
    'category': ['历史', '修真', '修真', '现实', '武侠', '都市', '仙侠', '仙侠', '武侠'],
    'price': [33.5, 26, 32.8, 29, 37, 25.5, 30.2, 28, 38],
    'num': [2, 1, 3, 6, 4, 8, 5, 3, 2]
})

group_df = df.groupby(by="category")

# filter:传入一个 lambda 函数表达式或一个函数筛选 DataFrame 中的列或行
# 类似 SQL 中 groupby 后的 having 操作
filter_df = group_df.filter(func=lambda x: x["price"].mean() > 30)

print(filter_df)

结果展示

    name category  price  num
0   三国演义       历史   33.5    2
4  射雕英雄传       武侠   37.0    4
8   神雕侠侣       武侠   38.0    2
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`agg`函数pandas中的一个聚合函数,用于对数据进行聚合操作。它可以接受一个或多个聚合函数作为参数,对分组后的数据进行聚合操作,并返回聚合后的结果。 `agg`函数的语法如下: ```python DataFrame.groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, observed=False).agg(func, *args, **kwargs) ``` 其中,`by`参数用于指定按照哪些列进行分组;`func`参数用于指定聚合函数,可以是预定义的函数,也可以是自定义的函数;`*args`和`**kwargs`参数用于传递聚合函数的参数。 下面是一个简单的例子,使用`agg`函数对数据进行聚合操作: ```python import pandas as pd # 创建数据集 data = { 'name': ['Alice', 'Bob', 'Charlie', 'David', 'Edward', 'Frank'], 'gender': ['F', 'M', 'M', 'M', 'M', 'M'], 'age': [25, 32, 18, 47, 23, 38], 'score': [85, 72, 90, 68, 92, 78] } df = pd.DataFrame(data) # 对数据进行分组和聚合 grouped = df.groupby('gender') result = grouped.agg({'age': ['mean', 'std'], 'score': 'max'}) print(result) ``` 输出结果如下: ``` age score mean std max gender F 25.000000 NaN 85 M 32.666667 11.198214 92 ``` 上面的代码中,我们首先创建了一个包含姓名、性别、年龄和分数的数据集。然后,我们使用`groupby`函数对数据按照性别进行分组。最后,我们使用`agg`函数分组后的数据进行聚合操作,计算每个性别的年龄的均值和标准差,以及分数的最大值。 在`agg`函数的参数中,我们使用字典来指定每个列需要进行的聚合操作。其中,字典的键表示需要聚合的列名,字典的值可以是一个或多个聚合函数。在本例中,我们对年龄列指定了均值和标准差两个聚合函数,对分数列指定了最大值聚合函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值