本文目录导读:

我来详细讲解如何使用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中数据分组重采样的主要应用场景,选择合适的重采样频率和填充方法对于数据分析非常重要。