Python Pandas 数据 GroupBy 分组操作详解:分组、聚合与遍历

Python Pandas 数据 GroupBy 分组操作详解:分组、聚合与遍历

本文详细介绍了Pandas中数据分组(GroupBy)的常用操作,包括按单列和多列分组、分组后的数据访问与聚合计算。通过实例讲解了如何使用groupby()方法对数据进行分组,并展示了如何使用first()last()等方法获取分组后的特定数据。此外,还介绍了如何使用agg()方法进行多种聚合计算,如求和、均值和标准差,及如何重命名聚合结果的列名。最后,提供了通过for循环遍历每个分组的示例,帮助读者深入理解Pandas中强大的数据分组和聚合功能。

导入第三方库

import pandas as pd
import numpy as np

一 数据分组

示例数据:

df = pd.DataFrame(
    [
        ("小红", "哈利波特", 80),
        ("小明", "蜘蛛侠", 72),
        ("小红", "雷神", 83),
        ("小红", "蜘蛛侠", 45),
        ("小明", "超人", 57),
    ],
    columns=("人", "人物", "评价"),
)
print(df)

运行结果

    人    人物  评价
0  小红  哈利波特  80
1  小明   蜘蛛侠  72
2  小红    雷神  83
3  小红   蜘蛛侠  45
4  小明    超人  57

按“人”进行分组

# 按“人”这一列进行分组,返回一个GroupBy对象
grouped = df.groupby("人")

# 打印GroupBy对象,输出的是一个表示分组操作的对象
print(grouped)

# 查看分组的具体内容,显示每个分组的键和对应的行索引
# 返回一个字典,键是分组的依据列(在这里是“人”),值是每个组对应的行索引
# {'小明': [1, 4], '小红': [0, 2, 3]}
print(grouped.groups)


# 通过行索引获取“小红”这一组的数据
# grouped.groups["小红"]返回的是“小红”这一组的行索引:[0, 2, 3]
# 使用iloc按这些索引从df中提取数据
print(df.iloc[grouped.groups["小红"]])

# 直接获取“小红”这一组的数据,get_group("小红")与iloc操作结果相同
print(grouped.get_group("小红"))
  • df.groupby("人"):按“人”这一列进行分组。此操作会根据“人”列的值(例如“小红”和“小明”)将数据分成若干组,返回一个GroupBy对象。
  • grouped.groups:查看分组后的数据,每个组的键(即“人”列的唯一值)与该组对应的行索引。
  • df.iloc[grouped.groups["小红"]]:根据“小红”组的行索引(0, 2, 3),使用iloc提取对应的行。
  • grouped.get_group("小红"):直接获取“小红”这一组的数据。

二 调用分组后的数据

# 调用分好的组,并对每个组执行不同的操作

# 1. 获取每个组的第一行数据
# .first()方法返回每个组的第一行数据
print(grouped.first())

# 2. 获取每个组的最后一行数据
# .last()方法返回每个组的最后一行数据
print(grouped.last())

# 3. 对每个组执行求和操作
# .sum()方法计算每个组的各列求和
# 这里会对“评价”列求和,如果是非数值类型列会被忽略
print(grouped.sum())

# 4. 获取“小红”组的“评价”列数据并计算其总和
# .get_group("小红")提取“小红”组的数据
# ["评价"]访问“评价”列,然后使用.sum()求该列的总和
print(grouped.get_group("小红")["评价"].sum())

for循环遍历分组

# 遍历每个分组,name是组名,group是每个组的数据
for name, group in grouped:
    # 输出组名
    print("name:", name)
    # 输出该组的数据
    print("group:", group)

四 多列分组

示例数据

# 创建一个DataFrame,包含三列:“人”、“人物”和“评价”
df = pd.DataFrame(
    [
        ("小红", "哈利波特", 80),
        ("小明", "蜘蛛侠", 72),
        ("小红", "雷神", 83),
        ("小红", "雷神", 90),
        ("小红", "蜘蛛侠", 45),
        ("小明", "超人", 57),
    ],
    columns=("人", "人物", "评价"),
)

# 打印原始的DataFrame
print(df)

多个列进行分组

# 按“人”和“人物”两列进行分组
print(df.groupby(["人", "人物"]).groups)
# 获取指定分组“('小红', '雷神')”的数据
print(df.groupby(["人", "人物"]).get_group(("小红", "雷神")))

五 聚合计算

# 按“人”这一列进行分组
grouped = df.groupby("人")

# 打印每个分组的键及其对应的行索引
print(grouped.groups)

# 使用聚合函数对每个分组进行求和操作,字符串列会被拼接在一起
print(grouped.aggregate(np.sum))

# 获取“小红”组的“评价”列数据,并应用聚合函数计算总和
print(grouped.get_group("小红")["评价"].aggregate(np.sum))

# 对“评价”列进行多个聚合操作:求和、均值和标准差
print(grouped["评价"].agg([np.sum, np.mean, np.std]))

# 对聚合结果重命名列名
print(grouped["评价"].agg([np.sum, np.mean, np.std]).rename(columns={"sum": "合计", "mean": "均值", "std": "标准差"}))
  • grouped.aggregate(np.sum):对每个分组进行求和操作,字符串列会被拼接在一起。
  • grouped.get_group("小红")["评价"].aggregate(np.sum):获取某个特定分组的某一列,并进行聚合。
  • grouped["评价"].agg([np.sum, np.mean, np.std]):对分组后的“评价”列应用多个聚合函数(如求和、均值和标准差)。
  • .rename(columns={...}):重命名聚合结果的列名,以便更好地理解输出。

六 完整代码示例

# This is a sample Python script.

# Press ⌃R to execute it or replace it with your code.
# Press Double ⇧ to search everywhere for classes, files, tool windows, actions, and settings.
import pandas as pd
import numpy as np


def print_hi(name):
    # Use a breakpoint in the code line below to debug your script.
    print(f'Hi, {name}')  # Press ⌘F8 to toggle the breakpoint.
    # 分组

    df = pd.DataFrame(
        [
            ("小红", "哈利波特", 80),
            ("小明", "蜘蛛侠", 72),
            ("小红", "雷神", 83),
            ("小红", "蜘蛛侠", 45),
            ("小明", "超人", 57),
        ],
        columns=("人", "人物", "评价"),
    )
    print(df)
    grouped = df.groupby("人")
    print(grouped)
    print(grouped.groups)
    print(df.iloc[grouped.groups["小红"]])
    print(grouped.get_group("小红"))

    # 调用分好的组
    print(grouped.first())
    print(grouped.last())
    print(grouped.sum())
    print(grouped.get_group("小红")["评价"].sum())

    # 循环处理
    for name, group in grouped:
        print("name:", name)
        print("group:", group)
    print()
    # 多列分组
    df = pd.DataFrame(
        [
            ("小红", "哈利波特", 80),
            ("小明", "蜘蛛侠", 72),
            ("小红", "雷神", 83),
            ("小红", "雷神", 90),
            ("小红", "蜘蛛侠", 45),
            ("小明", "超人", 57),
        ],
        columns=("人", "人物", "评价"),
    )
    print(df)
    print(df.groupby(["人", "人物"]).groups)
    print(df.groupby(["人", "人物"]).get_group(("小红", "雷神")))
    print()
    # 聚合计算
    grouped = df.groupby("人")
    print(grouped.groups)
    print(grouped.aggregate(np.sum))
    print(grouped.get_group("小红")["评价"].aggregate(np.sum))
    print(grouped["评价"].agg([np.sum, np.mean, np.std]))
    print(grouped["评价"].agg([np.sum, np.mean, np.std]).rename(columns={"sum": "合计", "mean": "均值", "std": "标准差"}))


# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    print_hi('数据分组 GroupBy')

# See PyCharm help at https://www.jetbrains.com/help/pycharm/

复制粘贴并覆盖到你的 main.py 中运行,运行结果如下。

Hi, 数据分组 GroupBy
    人    人物  评价
0  小红  哈利波特  80
1  小明   蜘蛛侠  72
2  小红    雷神  83
3  小红   蜘蛛侠  45
4  小明    超人  57
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x10286de20>
{'小明': [1, 4], '小红': [0, 2, 3]}
    人    人物  评价
0  小红  哈利波特  80
2  小红    雷神  83
3  小红   蜘蛛侠  45
    人    人物  评价
0  小红  哈利波特  80
2  小红    雷神  83
3  小红   蜘蛛侠  45
      人物  评价
人           
小明   蜘蛛侠  72
小红  哈利波特  80
     人物  评价
人          
小明   超人  57
小红  蜘蛛侠  45
           人物   评价
人                 
小明      蜘蛛侠超人  129
小红  哈利波特雷神蜘蛛侠  208
208
name: 小明
group:     人   人物  评价
1  小明  蜘蛛侠  72
4  小明   超人  57
name: 小红
group:     人    人物  评价
0  小红  哈利波特  80
2  小红    雷神  83
3  小红   蜘蛛侠  45

    人    人物  评价
0  小红  哈利波特  80
1  小明   蜘蛛侠  72
2  小红    雷神  83
3  小红    雷神  90
4  小红   蜘蛛侠  45
5  小明    超人  57
{('小明', '蜘蛛侠'): [1], ('小明', '超人'): [5], ('小红', '哈利波特'): [0], ('小红', '蜘蛛侠'): [4], ('小红', '雷神'): [2, 3]}
    人  人物  评价
2  小红  雷神  83
3  小红  雷神  90

{'小明': [1, 5], '小红': [0, 2, 3, 4]}
             人物   评价
人                   
小明        蜘蛛侠超人  129
小红  哈利波特雷神雷神蜘蛛侠  298
298
    sum  mean        std
人                       
小明  129  64.5  10.606602
小红  298  74.5  20.108042
     合计    均值        标准差
人                       
小明  129  64.5  10.606602
小红  298  74.5  20.108042

七 源码地址

代码地址:

国内看 Giteepandas/数据分组 GroupBy.py

国外看 GitHubpandas/数据分组 GroupBy.py

引用 莫烦 Python

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敲代码不忘补水

感谢有你,让我的创作更有价值!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值