Pandas 中的强大 groupby() 方法可以根据列值将 DataFrame 分割成多个部分。它允许使用“分割-应用-合并”策略应用 mean()、sum() 或 count() 等聚合函数。这对于汇总数据极其有用。然而,有时仅进行简单的聚合是不够的。你可能需要对每个分组单独执行更复杂的操作,查看每个分组内的数据,或者应用一个不完全符合标准聚合框架的函数。对于这些情况,Pandas 允许你直接遍历由 groupby() 创建的分组。当你对 DataFrame 调用 .groupby() 时,它不会立即计算出任何可见的结果,例如聚合。相反,它会返回一个特殊的 GroupBy 对象。此对象包含管理不同分组所需的所有信息。你可以将其看作是多个较小 DataFrame 的集合,其中每个 DataFrame 对应你分组所依据的列中一个唯一值(或值组合)。这个 GroupBy 对象是可迭代的,意味着你可以遍历它,就像你在 Python 中遍历列表一样。当你迭代 GroupBy 对象时,每次迭代都会生成一个包含两个元素的元组:分组名称(或名称): 这是定义当前分组的列中的唯一值。如果你按单个列分组,这将是一个单个值(例如字符串或数字)。如果你按多个列分组,这将是一个包含该分组值组合的元组。分组数据: 这是一个 DataFrame,只包含原始 DataFrame 中属于当前分组的行。标准的遍历方式是使用 for 循环:# 假设 'df' 是你的 DataFrame,'grouped' 是 GroupBy 对象 # grouped = df.groupby('要分组的列') for name, group_df in grouped: # 'name' 存储定义当前分组的值 # 'group_df' 是一个只包含该分组行的 DataFrame print(f"正在处理分组: {name}") # 你现在可以像处理标准 DataFrame 一样处理 group_df print(group_df.head(2)) # 示例:打印该分组的前2行 # 在此处执行自定义计算、筛选或可视化操作 print("-" * 20) # 用于分隔,更清晰让我们通过一个例子来说明。假设我们有一个小型 DataFrame,它记录了不同地区不同产品的销售数据:import pandas as pd data = {'Region': ['North', 'South', 'North', 'South', 'West', 'North', 'West'], 'Product': ['A', 'A', 'B', 'B', 'A', 'B', 'B'], 'Sales': [100, 150, 200, 250, 50, 210, 70]} sales_df = pd.DataFrame(data) print("原始 DataFrame:") print(sales_df) print("\n") # 按地区分组 grouped_by_region = sales_df.groupby('Region') print("按地区遍历分组:") for region_name, region_group in grouped_by_region: print(f"地区: {region_name}") print("该地区的数据:") print(region_group) print("-" * 30) 运行此代码将输出:原始 DataFrame: Region Product Sales 0 North A 100 1 South A 150 2 North B 200 3 South B 250 4 West A 50 5 North B 210 6 West B 70 按地区遍历分组: 地区: North 该地区的数据: Region Product Sales 0 North A 100 2 North B 200 5 North B 210 ------------------------------ 地区: South 该地区的数据: Region Product Sales 1 South A 150 3 South B 250 ------------------------------ 地区: West 该地区的数据: Region Product Sales 4 West A 50 6 West B 70 ------------------------------请注意,每次迭代都提供了 region_name(例如 'North'、'South'、'West')以及一个 region_group DataFrame,其中只包含匹配该地区的行。遍历多个分组列如果你按多个列分组,循环中的 name 变量将成为一个元组,其中包含定义该分组的值组合。# 同时按地区和产品分组 grouped_multi = sales_df.groupby(['Region', 'Product']) print("\n按地区和产品遍历分组:") for (region_name, product_name), group_data in grouped_multi: print(f"分组键: 地区={region_name}, 产品={product_name}") print("该分组的数据:") print(group_data) print("-" * 30)输出将显示由地区和产品的唯一配对定义的分组:按地区和产品遍历分组: 分组键: 地区=North, 产品=A 该分组的数据: Region Product Sales 0 North A 100 ------------------------------ 分组键: 地区=North, 产品=B 该分组的数据: Region Product Sales 2 North B 200 5 North B 210 ------------------------------ 分组键: 地区=South, 产品=A 该分组的数据: Region Product Sales 1 South A 150 ------------------------------ 分组键: 地区=South, 产品=B 该分组的数据: Region Product Sales 3 South B 250 ------------------------------ 分组键: 地区=West, 产品=A 该分组的数据: Region Product Sales 4 West A 50 ------------------------------ 分组键: 地区=West, 产品=B 该分组的数据: Region Product Sales 6 West B 70 ------------------------------何时使用遍历有益?虽然标准聚合函数(.sum()、.mean()、.agg())高效且适用于多种用例,但遍历分组在以下情况时有益:应用复杂函数: 你需要对每个分组应用一个函数,但该函数无法通过内置聚合方法或 agg() 中的 lambda 函数轻松表达。分组特定逻辑: 处理逻辑在不同分组之间差异很大,需要基于分组名称或其数据的条件语句。生成可视化: 你希望为每个分组创建单独的图表或可视化。遍历允许你顺序访问每个图表的数据。调试: 你需要检查每个分组的具体内容,以了解为什么聚合可能产生意料之外的结果。详细报告: 你需要生成一份报告,其中包含数据的每个部分的详细信息或特定计算。请记住,遍历分组的计算效率可能低于使用 Pandas 内置的聚合函数,特别是对于非常大的数据集。Pandas 用于标准聚合的向量化操作是高度优化的。因此,在可能的情况下,优先使用内置方法;当遍历提供的灵活性对你的特定任务是必需时,才使用它。