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
七 源码地址
代码地址:
国内看 Gitee 之 pandas/数据分组 GroupBy.py
国外看 GitHub 之 pandas/数据分组 GroupBy.py
引用 莫烦 Python