Python案例如何用Pandas做数据分组时序

wen python案例 1

本文目录导读:

Python案例如何用Pandas做数据分组时序

  1. 基础准备
  2. 基础分组操作
  3. 时序分组统计
  4. 高级时序分析
  5. 复杂时序分组案例
  6. 数据可视化
  7. 完整分析Pipeline

我来详细讲解如何使用Pandas进行数据分组和时序分析。

基础准备

import pandas as pd
import numpy as np
from datetime import datetime, timedelta
# 创建示例数据
np.random.seed(42)
# 生成时间序列数据
date_rng = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')
data = {
    'date': [],
    'product': [],
    'sales': [],
    'region': []
}
for product in ['A', 'B', 'C']:
    for region in ['North', 'South', 'East', 'West']:
        dates = pd.date_range(start='2023-01-01', periods=365, freq='D')
        data['date'].extend(dates)
        data['product'].extend([product] * 365)
        data['region'].extend([region] * 365)
        data['sales'].extend(np.random.randint(10, 100, 365))
df = pd.DataFrame(data)
print("数据形状:", df.shape)
print("\n数据预览:")
print(df.head())

基础分组操作

# 设置日期为索引
df['date'] = pd.to_datetime(df['date'])
df.set_index('date', inplace=True)
# 按产品和地区分组并计算统计量
group_stats = df.groupby(['product', 'region']).agg({
    'sales': ['sum', 'mean', 'std', 'min', 'max']
}).round(2)
print("分组统计:")
print(group_stats.head())

时序分组统计

按年/月/周分组

# 按年月分组
monthly_stats = df.groupby(['product', 'region', 
                            df.index.year, 
                            df.index.month])['sales'].agg(['sum', 'mean', 'count'])
monthly_stats.columns = ['total_sales', 'avg_sales', 'days_count']
print("\n月度统计:")
print(monthly_stats.head(10))
# 按周分组
weekly_stats = df.groupby(['product', df.index.isocalendar().week])['sales'].sum()
print("\n周度销量:")
print(weekly_stats.head())

滚动窗口计算

# 7天滚动平均
df['rolling_7d_mean'] = df.groupby(['product', 'region'])['sales']\
    .transform(lambda x: x.rolling(window=7, min_periods=1).mean())
# 30天滚动总和
df['rolling_30d_sum'] = df.groupby(['product', 'region'])['sales']\
    .transform(lambda x: x.rolling(window=30, min_periods=1).sum())
print("\n滚动计算示例:")
print(df[df['product'] == 'A'].head(10))

高级时序分析

同比和环比计算

# 准备数据
df_reset = df.reset_index()
df_reset['year'] = df_reset['date'].dt.year
df_reset['month'] = df_reset['date'].dt.month
# 环比计算
monthly_sales = df_reset.groupby(['product', 'region', 'year', 'month'])['sales'].sum().reset_index()
monthly_sales.sort_values(['product', 'region', 'year', 'month'], inplace=True)
# 计算环比增长率
monthly_sales['mom_change'] = monthly_sales.groupby(['product', 'region'])['sales']\
    .pct_change() * 100
# 计算同比增长率
monthly_sales['yoy_change'] = monthly_sales.groupby(['product', 'region'])['sales']\
    .transform(lambda x: x.pct_change(periods=12)) * 100
print("\n同比环比分析:")
print(monthly_sales[monthly_sales['product'] == 'A'].head(15))

季节性分析

# 添加季节标签
def get_season(month):
    if month in [3, 4, 5]:
        return 'Spring'
    elif month in [6, 7, 8]:
        return 'Summer'
    elif month in [9, 10, 11]:
        return 'Autumn'
    else:
        return 'Winter'
df_reset['season'] = df_reset['month'].apply(get_season)
# 季节性分组统计
seasonal_stats = df_reset.groupby(['product', 'region', 'season'])['sales'].agg([
    'sum', 'mean', 'std'
]).round(2)
print("\n季节性分析:")
print(seasonal_stats)

复杂时序分组案例

案例1:销售波动分析

# 计算每日波动率
df['daily_change'] = df.groupby(['product', 'region'])['sales'].pct_change()
# 找出异常波动
threshold = 0.5  # 50%波动阈值
df['is_anomaly'] = abs(df['daily_change']) > threshold
# 统计各产品异常天数
anomaly_stats = df[df['is_anomaly']].groupby(['product', 'region']).size()
print("\n异常波动统计:")
print(anomaly_stats)

案例2:累计达成率分析

# 假设月度目标是每个产品地区组合1000
monthly_target = 1000
# 计算累计销量和达成率
df['monthly_cumsum'] = df.groupby(['product', 'region', df.index.month])['sales'].cumsum()
df['achievement_rate'] = (df['monthly_cumsum'] / monthly_target * 100).round(1)
# 查看每月末的达成情况
monthly_end = df.groupby(['product', 'region', df.index.month]).last()
print("\n月度目标达成率:")
print(monthly_end[['achievement_rate']].head(10))

案例3:趋势分析

# 线性回归分析趋势
from scipy import stats
def trend_analysis(group):
    x = np.arange(len(group))
    y = group['sales'].values
    slope, intercept, r_value, p_value, std_err = stats.linregress(x, y)
    return pd.Series({
        'slope': slope,
        'r_squared': r_value**2,
        'p_value': p_value,
        'trend': '上升' if slope > 0 else '下降'
    })
# 各产品地区的销售趋势
trend_results = df.groupby(['product', 'region']).apply(trend_analysis)
print("\n销售趋势分析:")
print(trend_results)

数据可视化

import matplotlib.pyplot as plt
import seaborn as sns
# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 时间序列可视化
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
# 1. 各产品月度销量趋势
monthly_product = df_reset.groupby(['product', 'year', 'month'])['sales'].sum().reset_index()
monthly_product['date'] = pd.to_datetime(monthly_product[['year', 'month']].assign(day=1))
for product in ['A', 'B', 'C']:
    product_data = monthly_product[monthly_product['product'] == product]
    axes[0, 0].plot(product_data['date'], product_data['sales'], 
                    label=f'产品{product}', marker='o')
axes[0, 0].set_title('各产品月度销量趋势')
axes[0, 0].legend()
axes[0, 0].set_xlabel('日期')
axes[0, 0].set_ylabel('销量')
# 2. 地区销量热力图
region_monthly = df_reset.pivot_table(
    values='sales', 
    index=df_reset['date'].dt.month, 
    columns='region', 
    aggfunc='sum'
)
sns.heatmap(region_monthly, ax=axes[0, 1], cmap='YlOrRd', annot=True, fmt='.0f')
axes[0, 1].set_title('各地区月度销量分布')
# 3. 滚动平均对比
product_a = df[df['product'] == 'A'].groupby('region')['rolling_7d_mean']
for region in product_a.groups.keys():
    axes[1, 0].plot(product_a.get_group(region).head(100), 
                    label=f'{region}', alpha=0.7)
axes[1, 0].set_title('产品A 7天滚动平均')
axes[1, 0].legend()
# 4. 异常分布
anomaly_counts = df[df['is_anomaly']].groupby(['product', 'region']).size().unstack()
anomaly_counts.plot(kind='bar', ax=axes[1, 1])
axes[1, 1].set_title('异常波动分布')
axes[1, 1].set_ylabel('异常次数')
plt.tight_layout()
plt.show()

完整分析Pipeline

def complete_time_series_analysis(df):
    """
    完整的时序分组分析流程
    """
    # 1. 数据预处理
    df = df.copy()
    df['date'] = pd.to_datetime(df['date'])
    df.set_index('date', inplace=True)
    # 2. 基础统计
    basic_stats = df.groupby(['product', 'region']).agg({
        'sales': ['mean', 'std', 'min', 'max', 'count']
    })
    # 3. 时序特征
    df['month'] = df.index.month
    df['quarter'] = df.index.quarter
    df['weekday'] = df.index.weekday
    # 4. 滚动统计
    rolling_stats = df.groupby(['product', 'region'])['sales'].rolling(7).agg([
        'mean', 'std', 'min', 'max'
    ]).round(2)
    # 5. 增长率分析
    growth_rates = df.groupby(['product', 'region', 'month'])['sales'].sum()\
        .groupby(level=[0, 1]).pct_change() * 100
    return {
        'basic_stats': basic_stats,
        'rolling_stats': rolling_stats,
        'growth_rates': growth_rates,
        'processed_data': df
    }
# 运行完整分析
results = complete_time_series_analysis(df)
print("基础统计:")
print(results['basic_stats'])
print("\n增长率分析:")
print(results['growth_rates'].head())

这些案例覆盖了Pandas分组时序分析的主要应用场景,你可以根据实际需求进行调整和使用。

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