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

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

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

文章目录

  • Python Pandas 数据 GroupBy 分组操作详解:分组、聚合与遍历
  • 一 数据分组
  • 二 调用分组后的数据
  • 三 `for`循环遍历分组
  • 四 多列分组
  • 五 聚合计算
  • 六 完整代码示例
  • 七 源码地址
  • 导入第三方库

    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
    

    七 源码地址

    代码地址:

    国内看 Gitee 之 pandas/数据分组 GroupBy.py

    国外看 GitHub 之 pandas/数据分组 GroupBy.py

    引用 莫烦 Python

    作者:敲代码不忘补水

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python Pandas 数据 GroupBy 分组操作详解:分组、聚合与遍历

    发表回复