活动公告

系统通知
通知:本站资源由网友上传分享,如有违规等问题请到版务模块进行投诉,资源失效请在帖子内回复要求补档,会尽快处理!
10-23 09:31

探索Python Pandas时间处理函数的强大功能 从基础到进阶的时间序列数据分析技巧

SunJu_FaceMall

3万

主题

2720

科技点

3万

积分

执行版主

碾压王

积分
32881

塔罗立华奏

执行版主 发表于 2025-8-30 10:00:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
引言

时间序列数据是数据分析中最常见的数据类型之一,无论是金融市场的股票价格、气象数据的温度变化,还是网站访问量的日统计,都涉及到时间序列的分析。Python Pandas库提供了强大而灵活的时间处理功能,使得时间序列数据的操作和分析变得简单高效。本文将带领读者从基础到进阶,全面探索Pandas中时间处理函数的强大功能,并通过实际案例展示如何应用这些技巧解决实际问题。

1. 基础时间数据处理

1.1 时间数据类型的创建和转换

Pandas提供了两种主要的时间数据类型:Timestamp(表示单个时间点)和DatetimeIndex(表示时间序列)。让我们首先了解如何创建和转换这些时间数据类型。
  1. import pandas as pd
  2. import numpy as np
  3. # 创建单个时间点
  4. ts = pd.Timestamp('2023-01-01')
  5. print("单个时间点:", ts)
  6. print("时间类型:", type(ts))
  7. # 从字符串创建时间序列
  8. dates = ['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04']
  9. dt_index = pd.DatetimeIndex(dates)
  10. print("\n时间序列索引:", dt_index)
  11. # 将DataFrame的列转换为时间类型
  12. df = pd.DataFrame({'date': ['2023-01-01', '2023-01-02', '2023-01-03'],
  13.                    'value': [10, 20, 30]})
  14. df['date'] = pd.to_datetime(df['date'])
  15. print("\n转换后的DataFrame:")
  16. print(df)
  17. print("日期列的类型:", df['date'].dtype)
  18. # 从其他格式转换时间
  19. # 从Unix时间戳转换
  20. unix_timestamp = 1672531200  # 2023-01-01 00:00:00 UTC
  21. ts_from_unix = pd.to_datetime(unix_timestamp, unit='s')
  22. print("\n从Unix时间戳转换:", ts_from_unix)
  23. # 从Excel日期序列号转换
  24. excel_date = 44927  # 2023-01-01 in Excel date system
  25. ts_from_excel = pd.to_datetime(excel_date, unit='D', origin='1899-12-30')
  26. print("从Excel日期序列号转换:", ts_from_excel)
复制代码

1.2 时间索引的设置和使用

在时间序列分析中,将时间列设置为索引是非常常见的操作,这样可以方便地进行时间切片和聚合。
  1. # 创建带有时间索引的DataFrame
  2. date_rng = pd.date_range(start='2023-01-01', end='2023-01-10', freq='D')
  3. df = pd.DataFrame(date_rng, columns=['date'])
  4. df['data'] = np.random.randint(0, 100, size=(len(date_rng)))
  5. df.set_index('date', inplace=True)
  6. print("带有时间索引的DataFrame:")
  7. print(df)
  8. # 获取时间索引的各个部分
  9. df['year'] = df.index.year
  10. df['month'] = df.index.month
  11. df['day'] = df.index.day
  12. df['dayofweek'] = df.index.dayofweek  # 周一为0,周日为6
  13. df['hour'] = df.index.hour
  14. df['minute'] = df.index.minute
  15. df['second'] = df.index.second
  16. df['quarter'] = df.index.quarter  # 季度
  17. print("\n添加时间组件后的DataFrame:")
  18. print(df)
  19. # 使用时间组件进行筛选
  20. print("\n筛选工作日(周一到周五):")
  21. print(df[df['dayofweek'] < 5])  # 0-4为周一到周五
复制代码

1.3 基本的时间筛选和切片操作

Pandas提供了多种方式来筛选和切片时间序列数据,这些操作在时间序列分析中非常实用。
  1. # 扩展数据集以包含更多时间点
  2. extended_date_rng = pd.date_range(start='2023-01-01', end='2023-03-31', freq='D')
  3. extended_df = pd.DataFrame(extended_date_rng, columns=['date'])
  4. extended_df['value'] = np.random.randint(0, 100, size=(len(extended_date_rng)))
  5. extended_df.set_index('date', inplace=True)
  6. # 按日期范围切片
  7. print("2023年1月的数据:")
  8. print(extended_df['2023-01'])
  9. print("\n2023年1月15日到2月15日的数据:")
  10. print(extended_df['2023-01-15':'2023-02-15'])
  11. # 使用truncate方法进行切片
  12. print("\n使用truncate方法获取2023年2月的数据:")
  13. print(extended_df.truncate(before='2023-02-01', after='2023-02-28'))
  14. # 按条件筛选
  15. print("\n筛选所有周一的数据:")
  16. print(extended_df[extended_df.index.dayofweek == 0])  # 0表示周一
  17. # 使用between_time方法筛选一天中的特定时间段
  18. # 首先创建一个包含小时和分钟信息的DataFrame
  19. hourly_df = pd.DataFrame({
  20.     'time': pd.date_range(start='2023-01-01', end='2023-01-03', freq='H'),
  21.     'value': np.random.randint(0, 100, size=(48))
  22. })
  23. hourly_df.set_index('time', inplace=True)
  24. print("\n筛选每天9点到17点之间的数据:")
  25. print(hourly_df.between_time('09:00', '17:00'))
复制代码

2. 中级时间序列操作

2.1 时间重采样(Resample)

时间重采样是将时间序列数据从一个频率转换到另一个频率的过程,例如从日数据转换为月数据。Pandas的resample()方法使这一过程变得简单。
  1. # 创建一个包含分钟级数据的DataFrame
  2. minute_df = pd.DataFrame({
  3.     'time': pd.date_range(start='2023-01-01', end='2023-01-10', freq='T'),
  4.     'value': np.random.randint(0, 100, size=(60*24*10))  # 10天的分钟数据
  5. })
  6. minute_df.set_index('time', inplace=True)
  7. # 将分钟数据重采样为小时数据
  8. hourly_resampled = minute_df.resample('H').mean()  # 计算每小时的平均值
  9. print("重采样为小时数据(平均值):")
  10. print(hourly_resampled.head())
  11. # 使用不同的聚合函数
  12. print("\n重采样为小时数据(总和):")
  13. print(minute_df.resample('H').sum().head())
  14. print("\n重采样为小时数据(最大值):")
  15. print(minute_df.resample('H').max().head())
  16. # 重采样为日数据
  17. daily_resampled = minute_df.resample('D').agg(['mean', 'std', 'min', 'max'])
  18. print("\n重采样为日数据(多种统计量):")
  19. print(daily_resampled.head())
  20. # OHLC重采样(常用于金融数据)
  21. ohlc_resampled = minute_df['value'].resample('D').agg(
  22.     open='first',
  23.     high='max',
  24.     low='min',
  25.     close='last'
  26. )
  27. print("\nOHLC重采样:")
  28. print(ohlc_resampled.head())
  29. # 上采样和填充
  30. # 从日数据上采样到小时数据
  31. daily_sample_df = pd.DataFrame({
  32.     'date': pd.date_range(start='2023-01-01', end='2023-01-10', freq='D'),
  33.     'value': np.random.randint(0, 100, size=(10))
  34. })
  35. daily_sample_df.set_index('date', inplace=True)
  36. # 上采样到小时数据并填充缺失值
  37. upsampled = daily_sample_df.resample('H').asfreq()  # 默认填充NaN
  38. print("\n上采样到小时数据(不填充):")
  39. print(upsampled.head(24))
  40. # 使用不同的填充方法
  41. ffilled = daily_sample_df.resample('H').ffill()  # 前向填充
  42. bfilled = daily_sample_df.resample('H').bfill()  # 后向填充
  43. interpolated = daily_sample_df.resample('H').interpolate()  # 插值
  44. print("\n前向填充:")
  45. print(ffilled.head(24))
  46. print("\n插值填充:")
  47. print(interpolated.head(24))
复制代码

2.2 时间窗口操作(Rolling)

时间窗口操作允许我们在一个滑动的时间窗口上计算统计量,这对于平滑时间序列数据和计算移动平均等指标非常有用。
  1. # 创建一个包含随机波动的时间序列
  2. np.random.seed(42)
  3. window_df = pd.DataFrame({
  4.     'date': pd.date_range(start='2023-01-01', end='2023-03-31', freq='D'),
  5.     'value': np.random.normal(50, 10, size=(90))  # 均值为50,标准差为10
  6. })
  7. window_df.set_index('date', inplace=True)
  8. # 计算7天移动平均
  9. window_df['7_day_mean'] = window_df['value'].rolling(window=7).mean()
  10. window_df['7_day_std'] = window_df['value'].rolling(window=7).std()
  11. window_df['7_day_min'] = window_df['value'].rolling(window=7).min()
  12. window_df['7_day_max'] = window_df['value'].rolling(window=7).max()
  13. print("带有移动统计量的DataFrame:")
  14. print(window_df.head(10))
  15. # 计算指数加权移动平均
  16. window_df['ewm_mean'] = window_df['value'].ewm(span=7).mean()
  17. print("\n带有指数加权移动平均的DataFrame:")
  18. print(window_df[['value', '7_day_mean', 'ewm_mean']].head(10))
  19. # 使用rolling进行自定义计算
  20. # 例如,计算窗口内的最大值和最小值的差值
  21. window_df['range'] = window_df['value'].rolling(window=7).apply(lambda x: x.max() - x.min())
  22. print("\n带有自定义计算的DataFrame:")
  23. print(window_df[['value', 'range']].head(10))
  24. # 使用不同类型的窗口
  25. # 扩展窗口(expanding):从开始到当前点的所有数据
  26. window_df['expanding_mean'] = window_df['value'].expanding().mean()
  27. print("\n带有扩展窗口平均的DataFrame:")
  28. print(window_df[['value', 'expanding_mean']].head(10))
  29. # 累积求和
  30. window_df['cumsum'] = window_df['value'].cumsum()
  31. print("\n带有累积求和的DataFrame:")
  32. print(window_df[['value', 'cumsum']].head(10))
复制代码

2.3 时间Shift和差分操作

Shift和差分操作是时间序列分析中的重要工具,它们可以帮助我们比较不同时间点的数据,以及计算数据的变化率。
  1. # 创建一个示例DataFrame
  2. shift_df = pd.DataFrame({
  3.     'date': pd.date_range(start='2023-01-01', end='2023-01-31', freq='D'),
  4.     'value': np.random.randint(0, 100, size=(31))
  5. })
  6. shift_df.set_index('date', inplace=True)
  7. # 向前和向后shift
  8. shift_df['shifted_forward'] = shift_df['value'].shift(1)  # 向前移动一天
  9. shift_df['shifted_backward'] = shift_df['value'].shift(-1)  # 向后移动一天
  10. print("带有shift操作的DataFrame:")
  11. print(shift_df.head())
  12. # 计算日变化量
  13. shift_df['daily_change'] = shift_df['value'] - shift_df['shifted_forward']
  14. print("\n带有日变化量的DataFrame:")
  15. print(shift_df.head())
  16. # 计算百分比变化
  17. shift_df['pct_change'] = shift_df['value'].pct_change() * 100
  18. print("\n带有百分比变化的DataFrame:")
  19. print(shift_df.head())
  20. # 计算差分
  21. shift_df['diff'] = shift_df['value'].diff()  # 等同于 daily_change
  22. print("\n带有差分的DataFrame:")
  23. print(shift_df.head())
  24. # 计算多阶差分
  25. shift_df['second_diff'] = shift_df['value'].diff(periods=2)
  26. print("\n带有二阶差分的DataFrame:")
  27. print(shift_df.head())
  28. # 计算对数收益率(常用于金融分析)
  29. shift_df['log_return'] = np.log(shift_df['value'] / shift_df['value'].shift(1))
  30. print("\n带有对数收益率的DataFrame:")
  31. print(shift_df.head())
  32. # 计算移动窗口的百分比变化
  33. shift_df['rolling_pct_change'] = shift_df['value'].pct_change(periods=7) * 100
  34. print("\n带有7天窗口百分比变化的DataFrame:")
  35. print(shift_df.head(10))
复制代码

3. 高级时间序列处理

3.1 时区处理

在处理全球数据时,时区处理是一个重要的问题。Pandas提供了强大的时区处理功能,可以轻松地在不同时区之间转换。
  1. # 创建一个无时区的时间序列
  2. naive_dates = pd.date_range(start='2023-01-01', periods=10, freq='D')
  3. print("无时区的时间序列:")
  4. print(naive_dates)
  5. # 本地化时区
  6. localized_dates = naive_dates.tz_localize('UTC')  # 指定为UTC时区
  7. print("\n本地化为UTC时区:")
  8. print(localized_dates)
  9. # 转换为其他时区
  10. us_eastern = localized_dates.tz_convert('US/Eastern')
  11. print("\n转换为美国东部时区:")
  12. print(us_eastern)
  13. # 创建一个带有时区的DataFrame
  14. tz_df = pd.DataFrame({
  15.     'time': pd.date_range(start='2023-01-01', periods=24, freq='H', tz='UTC'),
  16.     'value': np.random.randint(0, 100, size=(24))
  17. })
  18. print("\n带有时区的DataFrame:")
  19. print(tz_df.head())
  20. # 转换整个DataFrame的时区
  21. tz_df['time'] = tz_df['time'].dt.tz_convert('Asia/Shanghai')
  22. print("\n转换为上海时区:")
  23. print(tz_df.head())
  24. # 处理不同时区的数据
  25. # 创建两个不同时区的时间序列
  26. utc_times = pd.date_range(start='2023-01-01', periods=5, freq='D', tz='UTC')
  27. eastern_times = pd.date_range(start='2023-01-01', periods=5, freq='D', tz='US/Eastern')
  28. # 转换为同一时区进行比较
  29. eastern_to_utc = eastern_times.tz_convert('UTC')
  30. print("\n美国东部时间转换为UTC:")
  31. print(eastern_to_utc)
  32. # 处理夏令时
  33. dst_dates = pd.date_range(start='2023-03-10', periods=4, freq='D', tz='US/Eastern')
  34. print("\n包含夏令时转换的日期:")
  35. print(dst_dates)
  36. # 创建一个跨越夏令时转换的时间序列
  37. dst_hourly = pd.date_range(start='2023-03-11 22:00', periods=6, freq='H', tz='US/Eastern')
  38. print("\n跨越夏令时转换的小时数据:")
  39. print(dst_hourly)
复制代码

3.2 时间周期和时期

Pandas中的Period对象表示固定的时间段,如某一天、某个月或某一年,这在处理周期性数据时非常有用。
  1. # 创建Period对象
  2. p1 = pd.Period('2023-01', freq='M')  # 2023年1月
  3. p2 = pd.Period('2023-01-01', freq='D')  # 2023年1月1日
  4. print("月度Period:", p1)
  5. print("日度Period:", p2)
  6. # Period的运算
  7. print("\nPeriod运算:")
  8. print("下一个月:", p1 + 1)
  9. print("上一个月:", p1 - 1)
  10. # 创建PeriodIndex
  11. periods = pd.period_range(start='2023-01', end='2023-12', freq='M')
  12. print("\n月度PeriodIndex:")
  13. print(periods)
  14. # 创建带有PeriodIndex的DataFrame
  15. period_df = pd.DataFrame({
  16.     'period': pd.period_range(start='2023-01', end='2023-06', freq='M'),
  17.     'value': np.random.randint(0, 100, size=(6))
  18. })
  19. period_df.set_index('period', inplace=True)
  20. print("\n带有PeriodIndex的DataFrame:")
  21. print(period_df)
  22. # 将时间戳转换为Period
  23. timestamp_df = pd.DataFrame({
  24.     'date': pd.date_range(start='2023-01-01', end='2023-06-30', freq='M'),
  25.     'value': np.random.randint(0, 100, size=(6))
  26. })
  27. timestamp_df['period'] = timestamp_df['date'].dt.to_period('M')
  28. print("\n将时间戳转换为Period:")
  29. print(timestamp_df)
  30. # 将Period转换为时间戳
  31. print("\n将Period转换为时间戳:")
  32. print(period_df.index.to_timestamp())
  33. # 使用Period进行时间范围查询
  34. print("\n查询2023年第一季度的数据:")
  35. print(period_df['2023-Q1'])  # Q1表示第一季度
  36. # 按季度聚合数据
  37. quarterly_df = period_df.resample('Q').sum()
  38. print("\n按季度聚合的数据:")
  39. print(quarterly_df)
复制代码

3.3 自定义时间频率和偏移量

Pandas提供了灵活的方式来定义自定义的时间频率和偏移量,这对于处理非标准时间间隔的数据非常有用。
  1. # 使用标准频率
  2. print("标准频率示例:")
  3. print(pd.date_range(start='2023-01-01', periods=5, freq='D'))  # 日
  4. print(pd.date_range(start='2023-01-01', periods=5, freq='W'))  # 周
  5. print(pd.date_range(start='2023-01-01', periods=5, freq='M'))  # 月
  6. print(pd.date_range(start='2023-01-01', periods=5, freq='Q'))  # 季度
  7. print(pd.date_range(start='2023-01-01', periods=5, freq='A'))  # 年
  8. # 使用自定义频率
  9. print("\n自定义频率示例:")
  10. print(pd.date_range(start='2023-01-01', periods=5, freq='2D'))  # 每2天
  11. print(pd.date_range(start='2023-01-01', periods=5, freq='3H'))  # 每3小时
  12. print(pd.date_range(start='2023-01-01', periods=5, freq='2W'))  # 每2周
  13. # 使用组合频率
  14. print("\n组合频率示例:")
  15. print(pd.date_range(start='2023-01-01', periods=5, freq='W-MON'))  # 每周一
  16. print(pd.date_range(start='2023-01-01', periods=5, freq='MS'))  # 每月第一天
  17. print(pd.date_range(start='2023-01-01', periods=5, freq='BMS'))  # 每月第一个工作日
  18. # 使用DateOffset对象
  19. print("\nDateOffset示例:")
  20. print(pd.date_range(start='2023-01-01', periods=5, freq=pd.DateOffset(days=2)))
  21. print(pd.date_range(start='2023-01-01', periods=5, freq=pd.DateOffset(weeks=1)))
  22. print(pd.date_range(start='2023-01-01', periods=5, freq=pd.DateOffset(months=1)))
  23. # 使用自定义业务日历
  24. from pandas.tseries.offsets import CustomBusinessDay
  25. # 创建一个自定义业务日历(排除周末)
  26. bday = CustomBusinessDay(weekmask='Mon Tue Wed Thu Fri')
  27. print("\n自定义业务日(排除周末):")
  28. print(pd.date_range(start='2023-01-01', periods=10, freq=bday))
  29. # 创建一个排除特定假日的业务日历
  30. from pandas.tseries.holiday import AbstractHolidayCalendar, Holiday, nearest_workday
  31. class MyCustomCalendar(AbstractHolidayCalendar):
  32.     rules = [
  33.         Holiday('New Year', month=1, day=1, observance=nearest_workday),
  34.         Holiday('My Custom Holiday', month=1, day=15)
  35.     ]
  36. my_bday = CustomBusinessDay(calendar=MyCustomCalendar())
  37. print("\n自定义业务日(排除周末和特定假日):")
  38. print(pd.date_range(start='2023-01-01', periods=10, freq=my_bday))
  39. # 使用锚定偏移量
  40. from pandas.tseries.offsets import MonthBegin, MonthEnd, QuarterBegin, QuarterEnd
  41. print("\n锚定偏移量示例:")
  42. print("月初:", pd.date_range(start='2023-01-01', periods=5, freq=MonthBegin()))
  43. print("月末:", pd.date_range(start='2023-01-01', periods=5, freq=MonthEnd()))
  44. print("季初:", pd.date_range(start='2023-01-01', periods=5, freq=QuarterBegin()))
  45. print("季末:", pd.date_range(start='2023-01-01', periods=5, freq=QuarterEnd()))
复制代码

4. 实战案例:使用Pandas进行时间序列数据分析

让我们通过一个实际案例来综合运用前面学到的Pandas时间处理技巧。假设我们有一组销售数据,需要进行分析和可视化。
  1. import matplotlib.pyplot as plt
  2. import seaborn as sns
  3. # 设置可视化风格
  4. sns.set(style="whitegrid")
  5. plt.rcParams['figure.figsize'] = (12, 6)
  6. # 创建示例销售数据
  7. np.random.seed(42)
  8. date_rng = pd.date_range(start='2021-01-01', end='2023-12-31', freq='D')
  9. sales_data = pd.DataFrame(date_rng, columns=['date'])
  10. sales_data['sales'] = np.random.randint(100, 1000, size=(len(date_rng)))
  11. sales_data.set_index('date', inplace=True)
  12. # 添加季节性模式(周末销售额更高)
  13. sales_data['day_of_week'] = sales_data.index.dayofweek
  14. sales_data['weekend'] = sales_data['day_of_week'].isin([5, 6])  # 5=周六, 6=周日
  15. sales_data.loc[sales_data['weekend'], 'sales'] *= 1.5  # 周末销售额增加50%
  16. # 添加月度趋势(月末销售额更高)
  17. sales_data['day_of_month'] = sales_data.index.day
  18. sales_data.loc[sales_data['day_of_month'] > 25, 'sales'] *= 1.2  # 月末销售额增加20%
  19. # 添加一些随机噪声
  20. sales_data['sales'] = sales_data['sales'] * np.random.normal(1, 0.1, size=(len(sales_data)))
  21. # 转换为整数
  22. sales_data['sales'] = sales_data['sales'].astype(int)
  23. print("销售数据示例:")
  24. print(sales_data.head())
  25. # 1. 基本时间序列分析
  26. # 按月重采样
  27. monthly_sales = sales_data['sales'].resample('M').sum()
  28. print("\n月度销售额:")
  29. print(monthly_sales.head())
  30. # 按季度重采样
  31. quarterly_sales = sales_data['sales'].resample('Q').sum()
  32. print("\n季度销售额:")
  33. print(quarterly_sales.head())
  34. # 2. 计算移动平均
  35. sales_data['7_day_ma'] = sales_data['sales'].rolling(window=7).mean()
  36. sales_data['30_day_ma'] = sales_data['sales'].rolling(window=30).mean()
  37. sales_data['90_day_ma'] = sales_data['sales'].rolling(window=90).mean()
  38. # 可视化移动平均
  39. plt.figure(figsize=(14, 7))
  40. plt.plot(sales_data.index, sales_data['sales'], alpha=0.3, label='日销售额')
  41. plt.plot(sales_data.index, sales_data['7_day_ma'], label='7天移动平均')
  42. plt.plot(sales_data.index, sales_data['30_day_ma'], label='30天移动平均')
  43. plt.plot(sales_data.index, sales_data['90_day_ma'], label='90天移动平均')
  44. plt.title('销售额及移动平均趋势')
  45. plt.xlabel('日期')
  46. plt.ylabel('销售额')
  47. plt.legend()
  48. plt.tight_layout()
  49. plt.show()
  50. # 3. 分析季节性模式
  51. # 按星期几分析
  52. weekday_sales = sales_data.groupby('day_of_week')['sales'].mean()
  53. weekday_sales.index = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
  54. plt.figure(figsize=(10, 5))
  55. weekday_sales.plot(kind='bar')
  56. plt.title('按星期几的平均销售额')
  57. plt.xlabel('星期')
  58. plt.ylabel('平均销售额')
  59. plt.tight_layout()
  60. plt.show()
  61. # 按月份分析
  62. monthly_avg = sales_data.groupby(sales_data.index.month)['sales'].mean()
  63. monthly_avg.index = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
  64. plt.figure(figsize=(10, 5))
  65. monthly_avg.plot(kind='bar')
  66. plt.title('按月份的平均销售额')
  67. plt.xlabel('月份')
  68. plt.ylabel('平均销售额')
  69. plt.tight_layout()
  70. plt.show()
  71. # 4. 年度同比分析
  72. # 按年月分组
  73. year_month_sales = sales_data.groupby([sales_data.index.year, sales_data.index.month])['sales'].sum()
  74. year_month_sales.index.names = ['年', '月']
  75. # 转换为DataFrame以便于比较
  76. year_month_df = year_month_sales.unstack(level=0)
  77. # 计算同比增长率
  78. year_month_df['YoY_growth'] = (year_month_df[2023] / year_month_df[2022] - 1) * 100
  79. print("\n年度同比分析:")
  80. print(year_month_df)
  81. # 可视化年度同比
  82. plt.figure(figsize=(10, 5))
  83. year_month_df['YoY_growth'].plot(kind='bar')
  84. plt.title('2023年相对于2022年的同比增长率')
  85. plt.xlabel('月份')
  86. plt.ylabel('增长率 (%)')
  87. plt.axhline(y=0, color='r', linestyle='-')
  88. plt.tight_layout()
  89. plt.show()
  90. # 5. 预测未来销售额(简单移动平均法)
  91. # 使用最后30天的平均销售额作为预测基准
  92. last_30_days_avg = sales_data['sales'].iloc[-30:].mean()
  93. # 创建未来30天的日期
  94. future_dates = pd.date_range(start=sales_data.index[-1] + pd.Timedelta(days=1), periods=30, freq='D')
  95. # 创建预测DataFrame
  96. forecast_df = pd.DataFrame(index=future_dates)
  97. forecast_df['forecast'] = last_30_days_avg
  98. # 添加季节性调整
  99. forecast_df['day_of_week'] = forecast_df.index.dayofweek
  100. forecast_df['weekend'] = forecast_df['day_of_week'].isin([5, 6])
  101. forecast_df.loc[forecast_df['weekend'], 'forecast'] *= 1.5  # 周末预测值增加50%
  102. # 合并历史数据和预测数据
  103. combined_df = pd.concat([sales_data['sales'], forecast_df['forecast']], axis=1)
  104. combined_df.columns = ['历史销售额', '预测销售额']
  105. # 可视化预测结果
  106. plt.figure(figsize=(14, 7))
  107. plt.plot(combined_df.index, combined_df['历史销售额'], label='历史销售额')
  108. plt.plot(combined_df.index, combined_df['预测销售额'], label='预测销售额', linestyle='--')
  109. plt.title('销售额历史数据与预测')
  110. plt.xlabel('日期')
  111. plt.ylabel('销售额')
  112. plt.legend()
  113. plt.tight_layout()
  114. plt.show()
复制代码

5. 总结与展望

本文全面介绍了Python Pandas库中时间处理函数的强大功能,从基础的时间数据类型创建和转换,到中级的重采样、窗口操作和shift差分,再到高级的时区处理、时间周期和自定义频率。通过实战案例,我们展示了如何将这些技巧应用于实际的时间序列数据分析中。

Pandas的时间处理功能之所以强大,在于它提供了直观而灵活的API,使得复杂的时间序列操作变得简单。无论是金融数据分析、气象数据处理,还是网站流量分析,Pandas都能提供高效的解决方案。

展望未来,随着数据量的不断增长和分析需求的日益复杂,时间序列分析将变得更加重要。Pandas也在不断发展和完善,例如与更专业的时序分析库(如statsmodels、Prophet等)的集成,以及对大数据处理的支持(如Dask)等。

掌握Pandas的时间处理功能,不仅能提高数据分析的效率,还能为更深入的时间序列建模和预测打下坚实的基础。希望本文能帮助读者更好地理解和应用Pandas中的时间处理函数,在实际工作中发挥其强大的功能。
「七転び八起き(ななころびやおき)」
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则