Python案例如何用Pandas做数据分组重采升级

wen python案例 9

本文目录导读:

Python案例如何用Pandas做数据分组重采升级

  1. 基础数据准备
  2. 按时间索引重采样
  3. 分组后重采样
  4. 实际应用案例
  5. 高级重采样技巧
  6. 数据插值方法
  7. 常见问题解决
  8. 性能优化建议

我来详细讲解如何使用Pandas进行数据分组和重采样(升采样)。

基础数据准备

import pandas as pd
import numpy as np
# 创建示例时间序列数据
dates = pd.date_range('2023-01-01', periods=30, freq='D')
df = pd.DataFrame({
    'date': dates,
    'group': np.random.choice(['A', 'B', 'C'], 30),
    'value': np.random.randint(10, 100, 30),
    'value2': np.random.randn(30).cumsum()
})

按时间索引重采样

1 基本重采样操作

# 设置时间索引
df.set_index('date', inplace=True)
# 降采样 - 按周聚合
weekly = df.resample('W').sum()
print("周降采样:")
print(weekly.head())
# 升采样 - 从天到小时(需要填充)
hourly = df.resample('H').ffill()  # 前向填充
print("\n小时升采样(前向填充):")
print(hourly.head(5))

2 不同类型重采样

# 不同聚合方法
resampled = df.resample('M').agg({
    'value': ['mean', 'sum', 'count'],
    'value2': ['std', 'min', 'max']
})
print("月重采样多种聚合:")
print(resampled)
# 降采样到不同频率
weekly_mean = df.resample('W').mean()  # 周均值
biweekly = df.resample('2W').sum()     # 双周汇总
monthly = df.resample('M').sum()       # 月汇总

分组后重采样

1 使用groupby配合resample

# 先分组,再在组内重采样
df_grouped = df.groupby('group').resample('W').sum()
print("分组后周重采样:")
print(df_grouped.head(10))
# 分组升采样
df_upsample = df.groupby('group').resample('D').ffill()
print("\n分组日升采样:")
print(df_upsample.head(10))

2 多级索引处理

# 创建多级索引数据
dates = pd.date_range('2023-01-01', periods=10, freq='D')
groups = ['A', 'B']
multi_index = pd.MultiIndex.from_product([groups, dates], names=['group', 'date'])
data = np.random.randn(20)
df_multi = pd.DataFrame({'value': data}, index=multi_index)
print("多级索引数据:")
print(df_multi)
# 对多级索引进行重采样
df_resampled = df_multi.groupby(level='group').resample('W').sum()
print("\n分组周重采样:")
print(df_resampled)

实际应用案例

1 股票数据重采样

# 模拟股票数据
stock_dates = pd.date_range('2023-01-01', periods=100, freq='D')
stock_data = pd.DataFrame({
    'stock': np.random.choice(['AAPL', 'GOOGL', 'MSFT'], 100),
    'price': np.random.uniform(100, 500, 100),
    'volume': np.random.randint(1000, 10000, 100),
    'date': stock_dates
})
stock_data.set_index('date', inplace=True)
# 按股票分组,周重采样
stock_weekly = stock_data.groupby('stock').resample('W').agg({
    'price': ['mean', 'min', 'max'],
    'volume': 'sum'
})
print("股票数据周重采样:")
print(stock_weekly.head(10))

2 销售数据重采样

# 模拟销售数据
sales_dates = pd.date_range('2023-01-01', periods=60, freq='D')
sales_data = pd.DataFrame({
    'store': np.random.choice(['Store_A', 'Store_B', 'Store_C'], 60),
    'product': np.random.choice(['Product_X', 'Product_Y'], 60),
    'sales': np.random.randint(50, 500, 60),
    'date': sales_dates
})
sales_data.set_index('date', inplace=True)
# 按门店和产品分组,月重采样
sales_monthly = sales_data.groupby(['store', 'product']).resample('M').sum()
print("销售数据月汇总:")
print(sales_monthly.head(10))

高级重采样技巧

1 自定义聚合函数

# 自定义聚合函数
def range_calc(x):
    return x.max() - x.min()
def weighted_average(x):
    weights = np.arange(1, len(x) + 1)
    return np.average(x, weights=weights)
# 应用自定义函数
custom_agg = df.groupby('group').resample('W').agg({
    'value': ['mean', range_calc, weighted_average],
    'value2': ['std', 'first', 'last']
})
print("自定义聚合函数:")
print(custom_agg.head(10))

2 条件重采样

# 基于条件的分组重采样
df['category'] = pd.cut(df['value'], bins=[0, 30, 60, 100], 
                         labels=['Low', 'Medium', 'High'])
# 按类别分组后重采样
category_resample = df.groupby('category').resample('W').agg({
    'value': ['mean', 'count'],
    'value2': 'mean'
})
print("基于类别的重采样:")
print(category_resample)

数据插值方法

# 不同插值方法在升采样中的应用
dates_irregular = pd.date_range('2023-01-01', periods=5, freq='3D')
df_irregular = pd.DataFrame({
    'value': [10, 20, 15, 30, 25],
    'date': dates_irregular
})
df_irregular.set_index('date', inplace=True)
# 不同填充方法
methods = ['ffill', 'bfill', 'linear', 'quadratic']
for method in methods:
    df_filled = df_irregular.resample('D').interpolate(method=method)
    print(f"\n{method} 插值结果:")
    print(df_filled.head(10))

常见问题解决

# 1. 处理缺失时间点
def fill_missing_times(df, freq='H'):
    """填补缺失的时间点"""
    full_idx = pd.date_range(df.index.min(), df.index.max(), freq=freq)
    return df.reindex(full_idx).ffill()
# 2. 处理不同分组的缺失值
def group_fill(df, group_col, freq='W'):
    """分组填充缺失值"""
    def fill_group(group):
        full_idx = pd.date_range(group.index.min(), group.index.max(), freq=freq)
        return group.reindex(full_idx).ffill()
    return df.groupby(group_col).apply(fill_group)

性能优化建议

# 优化大数据集的重采样
# 1. 使用更高效的数据类型
df_optimized = df.astype({
    'value': 'float32',
    'value2': 'float32'
})
# 2. 批量处理
def batch_resample(df, batch_size=10000):
    """分批处理重采样"""
    results = []
    n_batches = len(df) // batch_size + 1
    for i in range(n_batches):
        batch = df.iloc[i*batch_size:(i+1)*batch_size]
        resampled = batch.groupby('group').resample('W').sum()
        results.append(resampled)
    return pd.concat(results)

这些示例涵盖了Pandas中数据分组重采样的主要应用场景,选择合适的重采样频率和填充方法对于数据分析非常重要。

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