Python案例如何用Pandas做数据分组窗口

wen python案例 1

本文目录导读:

Python案例如何用Pandas做数据分组窗口

  1. 基础概念
  2. 准备工作
  3. 核心案例
  4. 实用案例:时间序列分析
  5. 高级应用:自定义窗口函数
  6. 窗口聚合操作
  7. 实战案例:股票数据分析
  8. 性能优化建议
  9. 关键要点

我来详细讲解Pandas中数据分组窗口的操作方法。

基础概念

分组窗口操作结合了 分组(groupby)窗口(window) 两个概念,可以在每个组内进行滑动窗口计算。

准备工作

import pandas as pd
import numpy as np
# 创建示例数据
df = pd.DataFrame({
    'group': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'B'],
    'date': pd.date_range('2024-01-01', periods=8, freq='D'),
    'value': [10, 20, 15, 25, 30, 35, 28, 40]
})
print(df)

核心案例

案例1:分组滚动窗口(移动平均)

# 计算每个组内3天的移动平均值
df['rolling_avg'] = df.groupby('group')['value'].transform(
    lambda x: x.rolling(window=3, min_periods=1).mean()
)
print("分组滚动平均:")
print(df)

案例2:分组扩展窗口

# 计算每个组内的累计平均值
df['expanding_mean'] = df.groupby('group')['value'].transform(
    lambda x: x.expanding().mean()
)
print("\n分组累计平均:")
print(df)

案例3:分组指数加权窗口

# 指数加权移动平均,更重视近期数据
df['ewm_mean'] = df.groupby('group')['value'].transform(
    lambda x: x.ewm(span=3, adjust=False).mean()
)
print("\n分组指数加权平均:")
print(df)

实用案例:时间序列分析

# 创建更真实的时间序列数据
dates = pd.date_range('2024-01-01', periods=20, freq='D')
sales_data = pd.DataFrame({
    'store': ['A', 'B', 'C'] * 7,
    'date': dates[:21],
    'sales': np.random.randint(100, 500, 21)
}).sort_values(['store', 'date']).reset_index(drop=True)
print("原始数据:")
print(sales_data.head(10))
# 案例:计算每个店铺7天移动平均销售额
sales_data['sales_7d_avg'] = sales_data.groupby('store')['sales'].transform(
    lambda x: x.rolling(window=7, min_periods=1).mean()
)
# 案例:计算每个店铺累计销售额
sales_data['cumulative_sales'] = sales_data.groupby('store')['sales'].transform(
    lambda x: x.expanding().sum()
)
# 案例:计算销售额环比增长率
sales_data['growth_rate'] = sales_data.groupby('store')['sales'].transform(
    lambda x: x.pct_change()
)
print("\n分析结果:")
print(sales_data)

高级应用:自定义窗口函数

# 自定义窗口计算
def custom_window_stats(series):
    """自定义窗口统计:返回窗口的最大值和最小值之差"""
    return series.rolling(window=3).apply(lambda x: x.max() - x.min(), raw=False)
df['range_3d'] = df.groupby('group')['value'].transform(custom_window_stats)
print("自定义窗口函数结果:")
print(df)

窗口聚合操作

# 使用agg进行多个聚合计算
window_funcs = ['mean', 'sum', 'std', 'min', 'max']
result = df.groupby('group')['value'].apply(
    lambda x: x.rolling(window=3, min_periods=1).agg(window_funcs)
)
print("\n多个聚合函数结果:")
print(result)

实战案例:股票数据分析

# 模拟股票数据
stock_data = pd.DataFrame({
    'stock': ['AAPL', 'AAPL', 'AAPL', 'GOOGL', 'GOOGL', 'GOOGL'] * 5,
    'date': pd.date_range('2024-01-01', periods=30, freq='D'),
    'price': np.random.uniform(100, 200, 30)
}).sort_values(['stock', 'date']).reset_index(drop=True)
# 案例:计算每只股票的技术指标
result = stock_data.groupby('stock').agg({
    'price': [
        ('5日移动均线', lambda x: x.rolling(5).mean()),
        ('10日移动均线', lambda x: x.rolling(10).mean()),
        ('5日波动率', lambda x: x.rolling(5).std()),
        ('20日累计收益', lambda x: x.rolling(20).apply(
            lambda y: (y.iloc[-1] - y.iloc[0]) / y.iloc[0] * 100
        ))
    ]
})
print("\n股票技术分析:")
print(result)

性能优化建议

# 方法1:使用transform避免groupby后的索引问题
df['optimized_rolling'] = df.groupby('group')['value'].transform(
    lambda x: x.rolling(3).mean()
)
# 方法2:对于大数据集,先排序再分组计算
df_sorted = df.sort_values(['group', 'date'])
df_sorted['rolling_avg'] = df_sorted.groupby('group')['value'].rolling(
    3, min_periods=1
).mean().values
# 方法3:使用pd.Grouper进行时间分组
df_time = df.set_index('date')
weekly_rolling = df_time.groupby('group').rolling('7D')['value'].mean()

关键要点

  1. 窗口类型

    • rolling(): 固定大小滑动窗口
    • expanding(): 扩展窗口
    • ewm(): 指数加权窗口
  2. 参数说明

    • min_periods: 最少有效值数量
    • window: 窗口大小
    • on: 指定时间列
  3. 常用方法

    • transform(): 保持原DataFrame形状
    • apply(): 灵活的自定义函数
    • agg(): 多个聚合函数

通过这些案例,你可以灵活运用Pandas进行各种分组窗口分析,根据实际需求选择合适的窗口类型和聚合函数。

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