Python案例如何用Pandas做数据分组导入

wen python案例 1

Python实战案例:用Pandas高效实现数据分组导入与批量处理

Python案例如何用Pandas做数据分组导入

文章目录导读

  1. 为什么需要数据分组导入?

    • 真实业务场景痛点分析
    • 分组导入 vs 逐条导入的性能对比
  2. Pandas数据分组核心功能速览

    • groupby() 本质与语法
    • 分组聚合函数(summeanagg
    • 分组后导出为独立文件或DataFrame列表
  3. 按销售区域分组导入CSV文件

    • 从Excel按城市拆分数据
    • 生成区域维度报表
  4. 时间序列分组与批量Excel输出

    • 按月份分组处理日志数据
    • 使用pd.ExcelWriter实现多Sheet导出
  5. 大型数据分块读取+分组处理

    • 使用chunksize避免内存溢出
    • 分组后合并中间结果
  6. 常见问题与面试问答(Q&A)

    • Q1:分组后如何保留原始行号?
    • Q2:如何对分组后的数据做条件过滤?
  7. 分组导入的最佳实践建议


为什么需要数据分组导入?

在实际数据分析工作中,我们经常遇到这样的场景:一个包含全国销售记录的5GB Excel文件,需要按省份生成独立报表;或者每天产生的用户行为日志,需要按月统计并保存为不同的CSV,如果手动筛选复制,不仅耗时且极易出错。Pandas的groupby()功能配合文件I/O操作,可以自动完成“按条件拆分-处理-导出”的全流程,将批量处理时间从小时级缩短到秒级。

相比传统的逐条循环读取(iterrows()),分组导入有以下优势:

  • 内存友好:直接对分组结果操作,避免重复加载全量数据
  • 代码简洁:三行代码即可完成按类别拆分与聚合
  • 可追溯性:分组后的索引保留原始数据标签

Pandas数据分组核心功能速览

1 groupby() 本质与语法

groupby()是Pandas中实现“拆分-应用-组合”的利器,其基础用法为:

grouped = df.groupby('column_name')

grouped是一个DataFrameGroupBy对象,它本身不进行计算,只保存分组规则,常见的后续操作包括:

  • 聚合.sum(), .mean(), .count()
  • 转换.transform() 保留原形状
  • 过滤.filter() 剔除不符合条件的分组

2 分组后导出为独立文件

核心技巧是利用groupby遍历每个分组的键和对应的子DataFrame:

for key, group in df.groupby('region'):
    group.to_csv(f'output/{key}.csv', index=False)

案例一:按销售区域分组导入CSV文件

目标:从sales_2024.csv(包含字段:日期城市销售额负责人)中,自动按城市生成若干子CSV文件,并附带每个城市的销售额汇总。

实现步骤:

import pandas as pd
# 读取源数据
df = pd.read_csv('sales_2024.csv')
# 按城市分组,并为每组生成独立文件
for city, group in df.groupby('城市'):
    # 保存原始数据
    group.to_csv(f'reports/{city}_detail.csv', index=False)
    # 同时生成该城市的聚合摘要
    summary = group.groupby('负责人')['销售额'].sum().reset_index()
    summary.to_csv(f'reports/{city}_summary.csv', index=False)
print('分组导入完成,共生成', df['城市'].nunique(), '个城市报表')

效果说明:

  • 若数据包含50个城市,则自动生成100个文件(50个明细 + 50个聚合)
  • 文件名使用城市名称,避免中文乱码问题(实际建议用英文或拼音)

案例二:时间序列分组与批量Excel输出

场景:某日志数据包含全年每天的用户活跃数(字段:日期用户ID活跃时长),需要按月份生成一个Excel文件,其中每个月份作为一个独立Sheet。

实现代码(带优化技巧):

import pandas as pd
from datetime import datetime
# 读取数据,确保日期列为datetime类型
df = pd.read_csv('user_log.csv', parse_dates=['日期'])
# 提取月份列
df['月份'] = df['日期'].dt.to_period('M')
# 使用ExcelWriter写入多Sheet
with pd.ExcelWriter('monthly_report.xlsx', engine='openpyxl') as writer:
    for month, group in df.groupby('月份'):
        # 将月份转换为字符串作为Sheet名称(Excel限制31字符)
        sheet_name = str(month)[:10]  
        # 计算该月日均活跃时长(演示聚合)
        summary = group.groupby('用户ID')['活跃时长'].mean().reset_index()
        summary.to_excel(writer, sheet_name=sheet_name, index=False)
print('已将全年数据按月份分组写入', len(df['月份'].unique()), '个Sheet')

关键点:

  • 使用dt.to_period('M')快速提取年月
  • ExcelWriterwith语句确保文件正确关闭
  • Sheet名称需避开Excel特殊字符(等)

案例三:大型数据分块读取+分组处理

问题:当源文件超过5GB时,直接pd.read_csv()可能导致内存溢出,解决方案是分块读取,每处理一个块即进行分组聚合,最后合并结果。

实现方案(增量式分组聚合):

import pandas as pd
chunk_size = 50000  # 每批5万行
final_result = []
for chunk in pd.read_csv('large_sales.csv', chunksize=chunk_size):
    # 对当前块按产品类别分组求和
    chunk_grouped = chunk.groupby('产品类别')['销售额'].sum()
    final_result.append(chunk_grouped)
# 合并所有分块的分组结果
final_series = pd.concat(final_result).groupby(level=0).sum()
final_series.to_csv('category_total.csv')
print('大型文件分组汇总完成,总行数约', chunk_size * len(final_result))

原理:

  • chunksize返回一个迭代器,每次读取指定行数
  • 每个切片独立groupby,结果用groupby(level=0).sum()二次聚合
  • 该模式适用于所有可累加的聚合函数(sum, count, min, max

常见问题与面试问答(Q&A)

Q1:分组后如何保留原始数据的行号?

如果需要在分组导出时保留原始行号(不重置索引),使用groupby内循环时直接用group即可,它包含原始行的索引。

for _, group in df.groupby('类别'):
    group.to_csv(...)  # 索引保持原样

若要强制重置索引,加reset_index(drop=True)

Q2:如何对分组后的数据做条件过滤?

使用groupby.filter()方法,例如只保留“平均评分高于4.0”的类别:

filtered_df = df.groupby('类别').filter(lambda x: x['评分'].mean() > 4.0)

注意返回的是原始DataFrame的子集,而非分组对象。

Q3:分组后字典嵌套存储实用吗?

对于需要频繁访问某个分组的场景,可以将分组结果转为字典:

groups_dict = {key: group for key, group in df.groupby('城市')}
# 直接访问 groups_dict['北京']

分组导入的最佳实践建议

  1. 先清洗后分组:分组前确保分组键没有空值(.dropna(subset=['分组列'])
  2. 文件命名规范:避免特殊字符,英文+下划线最稳定
  3. 大数据策略:优先使用chunksize + 增量聚合,避免一次性加载
  4. 动态列名处理:若分组键包含空格,导出时用sheet_name[:31]截断
  5. 性能监控:对超大量分组,使用tqdm库显示进度条:
    from tqdm import tqdm
    for key, group in tqdm(df.groupby('城市'), desc='分组进度'):
        ...

分组导入的核心思想是“拆解-独立处理-重组”,Pandas的groupby将这一思想以声明式语法实现,让数据工程师能够聚焦于业务逻辑而非遍历细节,掌握本文的三个案例,你便能够应对绝大多数日常数据分组导入需求。


延伸阅读:如需处理百万级以上的分组,可考虑使用dask库实现分布式分组,或配合polars进行列式加速。
代码仓库:所有案例代码已在GitHub开源(示例域名:github.com/data-group-example),欢迎Star与Issue讨论。

抱歉,评论功能暂时关闭!