本文目录导读:

我来详细讲解Pandas中数据分组窗口的操作方法。
基础概念
分组窗口操作结合了 分组(groupby) 和 窗口(window) 两个概念,可以在每个组内进行滑动窗口计算。
准备工作
import pandas as pd
import numpy as np
# 创建示例数据
df = pd.DataFrame({
'group': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'B'],
'date': pd.date_range('2024-01-01', periods=8, freq='D'),
'value': [10, 20, 15, 25, 30, 35, 28, 40]
})
print(df)
核心案例
案例1:分组滚动窗口(移动平均)
# 计算每个组内3天的移动平均值
df['rolling_avg'] = df.groupby('group')['value'].transform(
lambda x: x.rolling(window=3, min_periods=1).mean()
)
print("分组滚动平均:")
print(df)
案例2:分组扩展窗口
# 计算每个组内的累计平均值
df['expanding_mean'] = df.groupby('group')['value'].transform(
lambda x: x.expanding().mean()
)
print("\n分组累计平均:")
print(df)
案例3:分组指数加权窗口
# 指数加权移动平均,更重视近期数据
df['ewm_mean'] = df.groupby('group')['value'].transform(
lambda x: x.ewm(span=3, adjust=False).mean()
)
print("\n分组指数加权平均:")
print(df)
实用案例:时间序列分析
# 创建更真实的时间序列数据
dates = pd.date_range('2024-01-01', periods=20, freq='D')
sales_data = pd.DataFrame({
'store': ['A', 'B', 'C'] * 7,
'date': dates[:21],
'sales': np.random.randint(100, 500, 21)
}).sort_values(['store', 'date']).reset_index(drop=True)
print("原始数据:")
print(sales_data.head(10))
# 案例:计算每个店铺7天移动平均销售额
sales_data['sales_7d_avg'] = sales_data.groupby('store')['sales'].transform(
lambda x: x.rolling(window=7, min_periods=1).mean()
)
# 案例:计算每个店铺累计销售额
sales_data['cumulative_sales'] = sales_data.groupby('store')['sales'].transform(
lambda x: x.expanding().sum()
)
# 案例:计算销售额环比增长率
sales_data['growth_rate'] = sales_data.groupby('store')['sales'].transform(
lambda x: x.pct_change()
)
print("\n分析结果:")
print(sales_data)
高级应用:自定义窗口函数
# 自定义窗口计算
def custom_window_stats(series):
"""自定义窗口统计:返回窗口的最大值和最小值之差"""
return series.rolling(window=3).apply(lambda x: x.max() - x.min(), raw=False)
df['range_3d'] = df.groupby('group')['value'].transform(custom_window_stats)
print("自定义窗口函数结果:")
print(df)
窗口聚合操作
# 使用agg进行多个聚合计算
window_funcs = ['mean', 'sum', 'std', 'min', 'max']
result = df.groupby('group')['value'].apply(
lambda x: x.rolling(window=3, min_periods=1).agg(window_funcs)
)
print("\n多个聚合函数结果:")
print(result)
实战案例:股票数据分析
# 模拟股票数据
stock_data = pd.DataFrame({
'stock': ['AAPL', 'AAPL', 'AAPL', 'GOOGL', 'GOOGL', 'GOOGL'] * 5,
'date': pd.date_range('2024-01-01', periods=30, freq='D'),
'price': np.random.uniform(100, 200, 30)
}).sort_values(['stock', 'date']).reset_index(drop=True)
# 案例:计算每只股票的技术指标
result = stock_data.groupby('stock').agg({
'price': [
('5日移动均线', lambda x: x.rolling(5).mean()),
('10日移动均线', lambda x: x.rolling(10).mean()),
('5日波动率', lambda x: x.rolling(5).std()),
('20日累计收益', lambda x: x.rolling(20).apply(
lambda y: (y.iloc[-1] - y.iloc[0]) / y.iloc[0] * 100
))
]
})
print("\n股票技术分析:")
print(result)
性能优化建议
# 方法1:使用transform避免groupby后的索引问题
df['optimized_rolling'] = df.groupby('group')['value'].transform(
lambda x: x.rolling(3).mean()
)
# 方法2:对于大数据集,先排序再分组计算
df_sorted = df.sort_values(['group', 'date'])
df_sorted['rolling_avg'] = df_sorted.groupby('group')['value'].rolling(
3, min_periods=1
).mean().values
# 方法3:使用pd.Grouper进行时间分组
df_time = df.set_index('date')
weekly_rolling = df_time.groupby('group').rolling('7D')['value'].mean()
关键要点
-
窗口类型:
rolling(): 固定大小滑动窗口expanding(): 扩展窗口ewm(): 指数加权窗口
-
参数说明:
min_periods: 最少有效值数量window: 窗口大小on: 指定时间列
-
常用方法:
transform(): 保持原DataFrame形状apply(): 灵活的自定义函数agg(): 多个聚合函数
通过这些案例,你可以灵活运用Pandas进行各种分组窗口分析,根据实际需求选择合适的窗口类型和聚合函数。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播