本文目录导读:

我来详细讲解如何使用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())
主要要点:
- 基础流程:设置时间索引 → 分组 → 重采样 → 聚合
- 常用频率:H(小时)、D(天)、W(周)、M(月)、Q(季度)
- 聚合函数:mean、sum、std、min、max、count、自定义函数
- 缺失处理:ffill、bfill、fillna
- 性能优化:使用category类型、并行处理
这些案例覆盖了日常工作中最常见的分组重采样需求,可以根据实际场景灵活组合使用。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播