本文详细介绍 Pandas 的时间序列处理功能,包括:
# 创建时间戳
ts = pd.Timestamp('2023-01-01')
ts = pd.Timestamp('2023-01-01 12:00:00')
# 时间戳属性
print(ts.year) # 年份
print(ts.month) # 月份
print(ts.day) # 日期
print(ts.hour) # 小时
print(ts.minute) # 分钟
print(ts.second) # 秒
# 时间戳运算
ts + pd.Timedelta(days=1) # 加一天
ts - pd.Timedelta(hours=2) # 减两小时
# 创建时间范围
dates = pd.date_range('2023-01-01', '2023-01-10')
dates = pd.date_range('2023-01-01', periods=10)
dates = pd.date_range('2023-01-01', '2023-01-10', freq='D') # 按天
dates = pd.date_range('2023-01-01', '2023-01-10', freq='H') # 按小时
dates = pd.date_range('2023-01-01', '2023-01-10', freq='M') # 按月
# 时间范围属性
print(dates.start) # 开始时间
print(dates.end) # 结束时间
print(dates.freq) # 频率
# 常用频率
freq_D = pd.Timedelta(days=1) # 天
freq_H = pd.Timedelta(hours=1) # 小时
freq_M = pd.Timedelta(minutes=1) # 分钟
freq_S = pd.Timedelta(seconds=1) # 秒
# 自定义频率
freq_2D = pd.Timedelta(days=2) # 2天
freq_3H = pd.Timedelta(hours=3) # 3小时
freq_30M = pd.Timedelta(minutes=30) # 30分钟
# 创建时间索引
ts = pd.Series(range(10), index=pd.date_range('2023-01-01', periods=10))
# 时间索引选择
ts['2023-01-01'] # 选择特定日期
ts['2023-01'] # 选择特定月份
ts['2023'] # 选择特定年份
# 时间范围选择
ts['2023-01-01':'2023-01-05'] # 选择日期范围
ts['2023-01-01 12:00:00':'2023-01-01 13:00:00'] # 选择时间范围
# 降采样(降低频率)
ts.resample('D').sum() # 按天重采样
ts.resample('W').mean() # 按周重采样
ts.resample('M').count() # 按月重采样
# 升采样(提高频率)
ts.resample('H').ffill() # 前向填充
ts.resample('H').bfill() # 后向填充
ts.resample('H').interpolate() # 插值填充
# 自定义重采样
def custom_resample(x):
return x.max() - x.min()
ts.resample('D').apply(custom_resample)
# 时间移动
ts.shift(1) # 向后移动一个时间单位
ts.shift(-1) # 向前移动一个时间单位
ts.shift(1, freq='D') # 按天移动
# 时间滚动
ts.rolling(window=3).mean() # 3个时间单位的滚动平均
ts.rolling(window=3).std() # 3个时间单位的滚动标准差
ts.rolling(window=3).min() # 3个时间单位的滚动最小值
ts.rolling(window=3).max() # 3个时间单位的滚动最大值
# 固定窗口
ts.rolling(window=3).mean() # 固定3个时间单位的窗口
# 扩展窗口
ts.expanding().mean() # 从开始到当前的所有数据
# 指数加权窗口
ts.ewm(span=3).mean() # 指数加权移动平均
# 自定义窗口
def custom_window(x):
return x.max() - x.min()
ts.rolling(window=3).apply(custom_window)
# 移动平均
ts.rolling(window=7).mean() # 7天移动平均
ts.rolling(window=30).mean() # 30天移动平均
# 指数平滑
ts.ewm(span=7).mean() # 7天指数平滑
ts.ewm(span=30).mean() # 30天指数平滑
# 趋势分解
from statsmodels.tsa.seasonal import seasonal_decompose
decomposition = seasonal_decompose(ts, period=7)
trend = decomposition.trend
seasonal = decomposition.seasonal
residual = decomposition.resid
# 季节性分解
decomposition = seasonal_decompose(ts, period=7)
seasonal = decomposition.seasonal
# 季节性统计
ts.groupby(ts.index.month).mean() # 月度季节性
ts.groupby(ts.index.dayofweek).mean() # 周度季节性
ts.groupby(ts.index.hour).mean() # 小时季节性
# 季节性可视化
import matplotlib.pyplot as plt
seasonal.plot()
plt.title('季节性模式')
plt.show()
# 自相关分析
from statsmodels.tsa.stattools import acf
acf_values = acf(ts, nlags=40)
# 偏自相关分析
from statsmodels.tsa.stattools import pacf
pacf_values = pacf(ts, nlags=40)
# 周期性可视化
plt.figure(figsize=(12, 4))
plt.subplot(121)
plt.plot(acf_values)
plt.title('自相关函数')
plt.subplot(122)
plt.plot(pacf_values)
plt.title('偏自相关函数')
plt.show()
# 创建示例数据
dates = pd.date_range('2023-01-01', periods=100)
stock_data = pd.DataFrame({
'收盘价': np.random.randn(100).cumsum() + 100,
'成交量': np.random.randint(1000, 10000, 100)
}, index=dates)
# 计算移动平均
stock_data['MA5'] = stock_data['收盘价'].rolling(window=5).mean()
stock_data['MA20'] = stock_data['收盘价'].rolling(window=20).mean()
# 计算日收益率
stock_data['日收益率'] = stock_data['收盘价'].pct_change()
# 计算波动率
stock_data['波动率'] = stock_data['日收益率'].rolling(window=20).std()
# 按月份统计
monthly_stats = stock_data.resample('M').agg({
'收盘价': ['mean', 'std'],
'成交量': 'sum'
})
print("月度统计:")
print(monthly_stats)
# 创建示例数据
dates = pd.date_range('2023-01-01', periods=365)
sales_data = pd.DataFrame({
'销售额': np.random.randn(365).cumsum() + 1000,
'订单数': np.random.randint(10, 100, 365)
}, index=dates)
# 添加季节性
sales_data['销售额'] = sales_data['销售额'] + 100 * np.sin(np.arange(365) * 2 * np.pi / 365)
# 计算周度统计
weekly_stats = sales_data.resample('W').agg({
'销售额': ['sum', 'mean'],
'订单数': 'sum'
})
# 计算月度统计
monthly_stats = sales_data.resample('M').agg({
'销售额': ['sum', 'mean'],
'订单数': 'sum'
})
# 计算同比增长
sales_data['同比增长'] = sales_data['销售额'].pct_change(periods=365)
print("周度统计:")
print(weekly_stats)
print("\n月度统计:")
print(monthly_stats)
时间序列处理部分涵盖了:
掌握时间序列处理技术对于分析时间相关的数据至关重要。在实际应用中,这些技术可以帮助我们:
建议通过实际项目多加练习,熟悉各种时间序列处理方法的适用场景和组合使用方式。