Python案例如何用Pandas做数据分组重采方法

wen python案例 3

Python案例详解Pandas数据分组重采样方法(附完整代码)

目录导读

  1. 什么是Pandas数据分组重采样?
  2. 为什么需要分组重采样?——真实业务场景
  3. 核心函数:groupby() + resample() 的黄金组合
  4. 案例实战:股票日行情转周K线、销售数据月度聚合
  5. 常见错误与避坑指南
  6. 性能优化技巧(大数据量场景)
  7. 问答专区:你关心的5个高频问题

什么是Pandas数据分组重采样?

分组重采样是指先按照某个类别(如股票代码、门店ID)对数据进行分组,然后在每个分组内部按时间维度进行频率转换(将分钟数据汇总为小时数据,或日数据转为周数据)。

Python案例如何用Pandas做数据分组重采方法

简单说就是:先分组,再重采样,在Pandas中,我们通过 groupby()resample() 的链式调用实现。


为什么需要分组重采样?——真实业务场景

假设你是一家电商平台的数据分析师,每天需要处理以下任务:

  • 场景A:全国100家门店每小时的销售记录,要输出每个门店的日销售额
  • 场景B:沪深两市4000只股票每分钟的行情数据,需要生成每只股票的周K线
  • 场景C:物联网传感器每隔10秒上报的温湿度数据,需要按小时统计每个传感器平均温湿度

如果不分组直接重采样,你会把不同门店、不同股票的数值混在一起,结果毫无意义。分组重采样正是解决这类“多实体+时间序列”问题的标准方法


核心函数:groupby() + resample() 的黄金组合

Pandas实现分组重采样的标准语法为:

df.groupby('分组字段').resample('时间频率').聚合函数()

关键点:

  • 分组字段:通常是类别变量(如stock_codestore_id
  • 时间频率'D'(日)、'W'(周)、'M'(月)、'H'(小时)、'T'(分钟)等
  • 聚合函数mean()sum()ohlc()(金融专用)、自定义函数

注意resample() 要求时间列必须是 DatetimeIndexpd.to_datetime() 转换后的列,如果时间列不是索引,需指定 on 参数。


案例实战:完整Python代码演示

案例1:金融股票数据——日行情转周K线

数据模拟(实际可从雅虎财经等API获取)
import pandas as pd
import numpy as np
# 生成模拟数据:两只股票,5分钟频次,30天
np.random.seed(42)
dates = pd.date_range('2024-01-01', '2024-01-30', freq='5T')
stocks = ['AAPL', 'GOOGL']
data = []
for stock in stocks:
    price = np.random.uniform(100, 200, len(dates))
    data.extend([[stock, d, p] for d, p in zip(dates, price)])
df = pd.DataFrame(data, columns=['stock', 'time', 'close'])
print("原始数据形状:", df.shape)
执行分组重采样(转换为周OHLC格式)
# 关键步骤:先按股票分组,再按周重采样,输出开盘、最高、最低、收盘
weekly_ohlc = df.groupby('stock').resample('W', on='time')['close'].ohlc().reset_index()
print(weekly_ohlc.head(10))

输出解析:你会看到每个股票每周一条记录,包含Open、High、Low、Close四列,这正是金融领域标准的周K线数据结构。

案例2:零售销售数据——按门店+月汇总

# 模拟零售数据:3家门店,每天销售额
sales_data = {
    'store': ['A', 'B', 'C'] * 100,
    'date': pd.date_range('2024-01-01', periods=300, freq='D'),
    'revenue': np.random.randint(1000, 5000, 300)
}
df_sales = pd.DataFrame(sales_data)
# 按门店分组,按月汇总销售额
monthly_sales = df_sales.groupby('store').resample('M', on='date')['revenue'].sum()
print(monthly_sales)

常见错误与避坑指南

错误类型 典型代码 错误原因 正确做法
索引错误 df.resample('D').mean() 时间列不是索引 on参数或先set_index()
分组后索引混乱 groupby().resample()后直接plot 结果有多层索引 reset_index()平整化
缺失时间异常 数据日期不连续 重采样后出现NaN .ffill().fillna(0)
性能问题 逐行循环分组 大数据量时极慢 groupby().resample()向量化

最佳实践建议:先确保时间列为 datetime 类型,且数据按时间排序,可大幅提升效率。


性能优化技巧(大数据量场景)

当数据量超过100万行时,以下技巧能显著提升速度:

  1. 使用 resample()on 参数:避免多次 set_index() 导致内存拷贝
  2. 减少分组数量:如果分组字段有100万个唯一值,考虑先按天存分区文件
  3. 聚合函数选择sum()/mean() 比自定义lambda快3-5倍
  4. 关闭排序groupby(sort=False) 避免额外排序开销

问答专区:你关心的5个高频问题

Q1:分组重采样和普通重采样有什么区别?

A:普通重采样针对单条时间序列(如一只股票),分组重采样针对多实体(如100只股票)分别做时间转换,两者语法差异在于是否先调用 groupby()

Q2:时间列不是索引时如何处理?

A:使用 on 参数指定时间列:

df.groupby('stock').resample('W', on='trade_date').mean()

Q3:重采样后数据量变少,是否丢失信息?

A:不是丢失,是聚合——例如从分钟变为小时,一定会用均值或总和代表该时间段,这是合理的数据降维。

Q4:能否对重采样后的数据做窗口计算(如滚动均值)?

A:可以,在重采样结果基础上再次使用 .rolling(window=3).mean(),先聚合再平滑。

Q5:代码运行速度很慢,有什么建议?

A:优先检查数据量是否过大,尝试先用小数据测试逻辑;若需频繁执行,考虑将分组重采样后的结果存入数据库或分区Parquet文件。


延伸推荐:如果你想进一步学习,可以搜索“Pandas groupby resample multiple aggregations” 查看如何使用 agg() 同时计算均值、中位数、标准差等多种统计量。


本文示例代码均基于Python 3.10及Pandas 2.0+测试通过,建议使用Jupyter Notebook交互式运行以观察每一步输出。

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