Python案例如何用Pandas做数据分组滞后

wen python案例 1

本文目录导读:

Python案例如何用Pandas做数据分组滞后

  1. 基础分组滞后操作
  2. 完整案例:销售数据滞后分析
  3. 多列同时滞后
  4. 多层级分组滞后
  5. 固定窗口滚动滞后
  6. 实用的数据分析案例
  7. 滞后值填充技巧
  8. 性能优化技巧
  9. 常见问题及解决方案

我来详细讲解如何使用Pandas进行数据分组滞后(GroupBy Shift)操作,这是时间序列分析和面板数据处理中非常常见的需求。

基础分组滞后操作

基本语法

import pandas as pd
# 创建示例数据
df = pd.DataFrame({
    'group': ['A', 'A', 'A', 'B', 'B', 'B'],
    'value': [1, 2, 3, 4, 5, 6],
    'date': pd.date_range('2024-01-01', periods=6)
})
# 分组后计算滞后值
df['value_lag1'] = df.groupby('group')['value'].shift(1)
df['value_lag2'] = df.groupby('group')['value'].shift(2)

完整案例:销售数据滞后分析

案例场景

分析不同产品的销售额滞后效应,计算前一天和前两天的销售额。

import pandas as pd
import numpy as np
from datetime import datetime, timedelta
# 创建销售数据
np.random.seed(42)
dates = pd.date_range('2024-01-01', '2024-01-10', freq='D')
products = ['产品A', '产品B', '产品C']
data = []
for product in products:
    for date in dates:
        data.append({
            '产品': product,
            '日期': date,
            '销售额': np.random.randint(100, 1000)
        })
df_sales = pd.DataFrame(data)
print("原始数据:")
print(df_sales.head(10))

计算多种滞后值

# 按产品分组,计算滞后1天、2天和3天的销售额
df_sales = df_sales.sort_values(['产品', '日期'])
df_sales['销售-前一天'] = df_sales.groupby('产品')['销售额'].shift(1)
df_sales['销售-前两天'] = df_sales.groupby('产品')['销售额'].shift(2)
df_sales['销售-前三天'] = df_sales.groupby('产品')['销售额'].shift(3)
# 计算环比变化率
df_sales['环比变化率'] = (df_sales['销售额'] - df_sales['销售-前一天']) / df_sales['销售-前一天'] * 100
print("\n添加滞后值后的数据:")
print(df_sales.head(15))

多列同时滞后

# 创建包含多个指标的数据
df_multi = pd.DataFrame({
    'group': ['A', 'A', 'A', 'B', 'B', 'B'],
    'sales': [100, 150, 200, 300, 250, 350],
    'profit': [20, 30, 40, 60, 50, 70],
    'cost': [80, 120, 160, 240, 200, 280]
})
# 同时对多列进行滞后
cols_to_lag = ['sales', 'profit', 'cost']
lag_periods = 1
for col in cols_to_lag:
    df_multi[f'{col}_lag{lag_periods}'] = df_multi.groupby('group')[col].shift(lag_periods)
print("\n多列滞后数据:")
print(df_multi)

多层级分组滞后

# 多层级分组数据
df_multi_group = pd.DataFrame({
    'region': ['北', '北', '北', '南', '南', '南', '东', '东', '东'],
    'product': ['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C'],
    'price': [100, 120, 90, 110, 130, 95, 105, 125, 88],
    'date': pd.date_range('2024-01-01', periods=9)
})
# 按地区和产品双分组
df_multi_group['price_lag'] = df_multi_group.groupby(['region', 'product'])['price'].shift(1)
print("\n多层级分组滞后:")
print(df_multi_group)

固定窗口滚动滞后

# 滚动窗口计算
df_rolling = pd.DataFrame({
    'group': ['A'] * 10 + ['B'] * 10,
    'value': range(1, 21),
    'date': pd.date_range('2024-01-01', periods=20)
})
# 定义函数计算滚动统计
def rolling_stats(group):
    return group.sort_values('date').rolling(window=3).agg({
        'value': ['mean', 'std', 'min', 'max']
    })
# 应用分组滚动
result = df_rolling.groupby('group').apply(
    lambda x: x.set_index('date').rolling('3D').mean()
)
print("\n滚动窗口统计:")
print(result.head(10))

实用的数据分析案例

股票收益率分析

# 模拟股票数据
stocks = ['AAPL', 'GOOGL', 'MSFT']
dates = pd.date_range('2024-01-01', '2024-01-20', freq='D')
stock_data = []
for stock in stocks:
    price = 100
    for date in dates:
        price *= (1 + np.random.normal(0, 0.02))
        stock_data.append({
            '股票': stock,
            '日期': date,
            '价格': round(price, 2)
        })
df_stock = pd.DataFrame(stock_data)
df_stock = df_stock.sort_values(['股票', '日期'])
# 计算收益率和滞后收益率
df_stock['收益率'] = df_stock.groupby('股票')['价格'].pct_change() * 100
df_stock['收益-前一天'] = df_stock.groupby('股票')['收益率'].shift(1)
df_stock['收益-前两天'] = df_stock.groupby('股票')['收益率'].shift(2)
print("\n股票收益率分析:")
print(df_stock.head(15))

滞后值填充技巧

# 处理缺失值
df_na = pd.DataFrame({
    'group': ['A', 'A', 'A', 'A', 'B', 'B', 'B'],
    'value': [10, np.nan, 30, 40, 50, np.nan, 70],
    'date': pd.date_range('2024-01-01', periods=7)
})
# 向前填充缺失值后再计算滞后
df_na['value_filled'] = df_na.groupby('group')['value'].fillna(method='ffill')
df_na['value_lag'] = df_na.groupby('group')['value_filled'].shift(1)
print("\n处理缺失值后的滞后:")
print(df_na)

性能优化技巧

# 大数据集处理优化
import time
# 创建大数据集
big_data = pd.DataFrame({
    'group': np.random.choice(range(1000), 100000),
    'value': np.random.randn(100000),
    'date': pd.date_range('2024-01-01', periods=100000, freq='H')
})
# 优化方法1:设置索引后再分组
start_time = time.time()
result1 = big_data.set_index('date').groupby('group')['value'].shift(1)
print(f"方法1耗时: {time.time() - start_time:.3f}秒")
# 优化方法2:使用transform函数
start_time = time.time()
result2 = big_data.groupby('group')['value'].transform(
    lambda x: x.shift(1)
)
print(f"方法2耗时: {time.time() - start_time:.3f}秒")

常见问题及解决方案

  1. 数据未排序导致的错误

    # 正确的做法:先排序再分组
    df_sorted = df.sort_values(['group', 'date'])
    df_sorted['lag'] = df_sorted.groupby('group')['value'].shift(1)
  2. 多列不同滞后周期

    # 定义滞后配置
    lag_config = {
     'sales': 1,
     'profit': 2,
     'cost': 3
    }

for col, periods in lag_config.items(): df[f'{col}_lag{periods}'] = df.groupby('group')[col].shift(periods)


## 
使用Pandas进行分组滞后操作的核心要点:
1. **先排序**:确保按分组列和时间列排序
2. **使用groupby+shift**:这是最直接的方法
3. **注意数据类型**:确保时间是datetime类型
4. **处理缺失值**:合理填充或处理NA值
5. **性能优化**:大数据集考虑使用transform
这些技巧在金融数据分析、销售预测、时间序列研究等领域非常实用。

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