Python案例如何用Pandas做数据分组重采部署

wen python案例 6

本文目录导读:

Python案例如何用Pandas做数据分组重采部署

  1. 基础环境准备
  2. 案例1:按组和时间重采样
  3. 案例2:不同时间频率的重采样
  4. 案例3:多列重采样
  5. 案例4:向前向后填充
  6. 案例5:自定义重采样规则
  7. 案例6:数据可视化
  8. 案例7:窗口滚动重采样
  9. 完整实用示例
  10. 性能优化技巧

我来详细讲解如何使用Pandas进行数据分组重采样,包含多个实用案例。

基础环境准备

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-03-31', freq='H')
groups = ['A', 'B', 'C']
# 创建DataFrame
data = {
    'timestamp': np.random.choice(dates, 1000),
    'group': np.random.choice(groups, 1000),
    'value': np.random.randn(1000) * 10 + 50,
    'count': np.random.randint(1, 100, 1000)
}
df = pd.DataFrame(data)
df = df.sort_values('timestamp')
print("原始数据预览:")
print(df.head())

案例1:按组和时间重采样

1 按天重采样并计算均值

# 方法1:使用groupby和resample
df_daily_mean = (df.set_index('timestamp')
                 .groupby('group')
                 .resample('D')['value']
                 .mean()
                 .reset_index())
print("按天重采样(均值):")
print(df_daily_mean.head(10))

2 多种聚合函数组合

# 同时计算多个统计量
df_daily_stats = (df.set_index('timestamp')
                  .groupby('group')
                  .resample('D')['value']
                  .agg(['mean', 'std', 'min', 'max', 'count'])
                  .reset_index())
print("\n按天重采样(多统计量):")
print(df_daily_stats.head(10))

案例2:不同时间频率的重采样

# 3.1 按小时重采样
df_hourly = (df.set_index('timestamp')
             .groupby('group')
             .resample('H')['value']
             .mean()
             .fillna(0)
             .reset_index())
print("按小时重采样:")
print(df_hourly.head())
# 3.2 按周重采样
df_weekly = (df.set_index('timestamp')
             .groupby('group')
             .resample('W')['value']
             .mean()
             .reset_index())
print("\n按周重采样:")
print(df_weekly.head())
# 3.3 按月重采样
df_monthly = (df.set_index('timestamp')
              .groupby('group')
              .resample('M')['value']
              .mean()
              .reset_index())
print("\n按月重采样:")
print(df_monthly)

案例3:多列重采样

# 对多列进行不同的聚合操作
df_multi = (df.set_index('timestamp')
            .groupby('group')
            .resample('D')
            .agg({
                'value': ['mean', 'std'],
                'count': ['sum', 'mean']
            })
            .reset_index())
print("多列重采样:")
print(df_multi.head(10))
# 简化列名
df_multi.columns = ['_'.join(col).strip('_') for col in df_multi.columns.values]
print("\n简化列名后:")
print(df_multi.head())

案例4:向前向后填充

# 创建包含缺失值的数据
dates_missing = pd.date_range('2024-01-01', periods=20, freq='H')
groups_missing = ['A', 'B']
df_missing = pd.DataFrame({
    'timestamp': np.random.choice(dates_missing, 30),
    'group': np.random.choice(groups_missing, 30),
    'value': np.random.randn(30) * 10 + 50
}).drop_duplicates(subset=['timestamp', 'group'])
print("原始缺失数据:")
print(df_missing.head())
# 重采样并填充缺失值
df_filled = (df_missing.set_index('timestamp')
             .groupby('group')
             .resample('H')['value']
             .mean()
             .fillna(method='ffill')  # 向前填充
             .reset_index())
print("\n填充后的数据:")
print(df_filled.head(10))

案例5:自定义重采样规则

# 自定义时间偏移
from pandas.tseries.offsets import DateOffset
# 每2天重采样
df_2day = (df.set_index('timestamp')
           .groupby('group')
           .resample('2D')['value']
           .mean()
           .reset_index())
print("每2天重采样:")
print(df_2day.head())
# 自定义聚合函数
def custom_agg(x):
    return np.percentile(x, 75) - np.percentile(x, 25)
df_custom = (df.set_index('timestamp')
             .groupby('group')
             .resample('W')
             .agg({
                 'value': ['mean', custom_agg],
                 'count': 'sum'
             })
             .reset_index())
print("\n自定义聚合函数:")
print(df_custom.head())

案例6:数据可视化

import matplotlib.pyplot as plt
# 准备可视化数据
plot_data = df.set_index('timestamp')
# 绘制不同组的时间序列
fig, axes = plt.subplots(3, 1, figsize=(12, 10))
for i, group in enumerate(groups):
    group_data = plot_data[plot_data['group'] == group]
    daily_mean = group_data.resample('D')['value'].mean()
    axes[i].plot(daily_mean.index, daily_mean.values, label=f'Group {group}')
    axes[i].set_title(f'Group {group} - Daily Mean')
    axes[i].set_xlabel('Date')
    axes[i].set_ylabel('Value')
    axes[i].legend()
    axes[i].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()

案例7:窗口滚动重采样

# 滚动窗口统计
df_rolling = (df.set_index('timestamp')
              .groupby('group')
              .resample('D')['value']
              .mean()
              .reset_index())
# 计算7天滚动均值
df_rolling['rolling_mean_7d'] = (df_rolling.groupby('group')
                                 ['value']
                                 .transform(lambda x: x.rolling(7, min_periods=1).mean()))
print("滚动窗口重采样:")
print(df_rolling.head(10))

完整实用示例

def analyze_time_series(df, timestamp_col, group_col, value_col, 
                       resample_freq='D', agg_func='mean'):
    """
    完整的时间序列分析函数
    Parameters:
    -----------
    df : DataFrame
        输入数据
    timestamp_col : str
        时间戳列名
    group_col : str
        分组列名
    value_col : str
        数值列名
    resample_freq : str
        重采样频率 ('D', 'W', 'M', 'H'等)
    agg_func : str
        聚合函数 ('mean', 'sum', 'std'等)
    """
    # 设置时间索引
    df_processed = df.set_index(timestamp_col)
    # 分组重采样
    result = (df_processed.groupby(group_col)
              .resample(resample_freq)[value_col]
              .agg(agg_func)
              .reset_index())
    # 添加统计信息
    result.columns = [timestamp_col, group_col, value_col]
    # 计算变化率
    result['pct_change'] = (result.groupby(group_col)[value_col]
                           .transform(lambda x: x.pct_change() * 100))
    # 计算累计和
    result['cumsum'] = (result.groupby(group_col)[value_col]
                       .transform('cumsum'))
    return result
# 使用示例
analysis_result = analyze_time_series(
    df, 
    timestamp_col='timestamp',
    group_col='group', 
    value_col='value',
    resample_freq='D',
    agg_func='mean'
)
print("完整分析结果:")
print(analysis_result.head(15))

性能优化技巧

# 10.1 使用分类变量加速
df['group'] = df['group'].astype('category')
# 10.2 批量处理多个频率
def multi_freq_resample(df, freq_list=['D', 'W', 'M']):
    results = {}
    for freq in freq_list:
        result = (df.set_index('timestamp')
                  .groupby('group')
                  .resample(freq)['value']
                  .mean()
                  .reset_index())
        results[freq] = result
    return results
# 10.3 并行处理(使用多进程)
from joblib import Parallel, delayed
def parallel_resample(df, freq):
    return (df.set_index('timestamp')
            .groupby('group')
            .resample(freq)['value']
            .mean()
            .reset_index())
# 执行并行重采样
freqs = ['D', 'W', 'M', 'Q']
results = Parallel(n_jobs=-1)(
    delayed(parallel_resample)(df, freq) for freq in freqs
)
for freq, result in zip(freqs, results):
    print(f"\n{freq}频率重采样结果:")
    print(result.head())

主要要点:

  1. 基础流程:设置时间索引 → 分组 → 重采样 → 聚合
  2. 常用频率:H(小时)、D(天)、W(周)、M(月)、Q(季度)
  3. 聚合函数:mean、sum、std、min、max、count、自定义函数
  4. 缺失处理:ffill、bfill、fillna
  5. 性能优化:使用category类型、并行处理

这些案例覆盖了日常工作中最常见的分组重采样需求,可以根据实际场景灵活组合使用。

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