活动公告

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

Pandas时间戳从入门到精通高效处理时间数据提升分析能力必备技巧

SunJu_FaceMall

3万

主题

2860

科技点

3万

积分

白金月票

碾压王

积分
32872

塔罗立华奏

<font color=白金月票" /> 发表于 2025-9-2 10:50:00 | 显示全部楼层 |阅读模式

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

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

x
引言

在数据分析领域,时间数据无处不在。无论是金融市场的股票价格、气象数据的温度记录,还是网站的用户访问日志,时间都是关键的维度。正确高效地处理时间数据,能够帮助我们揭示数据中的时间模式、趋势和周期性,从而做出更准确的预测和决策。

Pandas作为Python数据分析的核心库,提供了强大而灵活的时间数据处理功能。其中,时间戳(Timestamp)是处理时间数据的基础。本文将带你从基础概念到高级应用,全面掌握Pandas时间戳的处理技巧,提升你的数据分析能力。

Pandas时间戳基础

什么是时间戳

时间戳是表示特定时间点的对象,在Pandas中,Timestamp是对Python标准库datetime的扩展,提供了更多的功能和更好的性能。它可以精确到纳秒级别,并支持时区操作。

创建时间戳

在Pandas中,有多种方式可以创建时间戳对象:
  1. import pandas as pd
  2. from datetime import datetime
  3. # 使用字符串创建时间戳
  4. ts1 = pd.Timestamp('2023-01-15')
  5. print(ts1)
  6. # 输出: 2023-01-15 00:00:00
  7. # 使用更详细的字符串
  8. ts2 = pd.Timestamp('2023-01-15 14:30:25')
  9. print(ts2)
  10. # 输出: 2023-01-15 14:30:25
  11. # 使用datetime对象
  12. dt = datetime(2023, 1, 15, 14, 30, 25)
  13. ts3 = pd.Timestamp(dt)
  14. print(ts3)
  15. # 输出: 2023-01-15 14:30:25
  16. # 使用Unix时间戳(秒)
  17. ts4 = pd.Timestamp(1673775025)
  18. print(ts4)
  19. # 输出: 2023-01-15 14:30:25
  20. # 使用参数创建
  21. ts5 = pd.Timestamp(year=2023, month=1, day=15, hour=14, minute=30, second=25)
  22. print(ts5)
  23. # 输出: 2023-01-15 14:30:25
复制代码

获取当前时间戳
  1. # 获取当前时间戳
  2. now = pd.Timestamp.now()
  3. print(now)
  4. # 输出类似: 2023-11-05 10:30:45.123456
  5. # 获取当前日期(时间为00:00:00)
  6. today = pd.Timestamp.today()
  7. print(today)
  8. # 输出类似: 2023-11-05 00:00:00
复制代码

时间戳的属性和方法

Pandas时间戳对象提供了丰富的属性和方法,方便我们访问和操作时间的各个组成部分。

访问时间组件
  1. ts = pd.Timestamp('2023-01-15 14:30:25.123456')
  2. # 获取年、月、日、时、分、秒
  3. print(ts.year)      # 输出: 2023
  4. print(ts.month)     # 输出: 1
  5. print(ts.day)       # 输出: 15
  6. print(ts.hour)      # 输出: 14
  7. print(ts.minute)    # 输出: 30
  8. print(ts.second)    # 输出: 25
  9. print(ts.microsecond)  # 输出: 123456
  10. print(ts.nanosecond)   # 输出: 123456000
  11. # 获取星期几(0=周一,6=周日)
  12. print(ts.dayofweek)  # 输出: 6 (周日)
  13. print(ts.day_name()) # 输出: Sunday
  14. # 获取一年中的第几天
  15. print(ts.dayofyear)  # 输出: 15
  16. # 获取季度
  17. print(ts.quarter)    # 输出: 1
  18. # 获取是否为月末
  19. print(ts.is_month_end)  # 输出: False
  20. # 获取是否为季末
  21. print(ts.is_quarter_end)  # 输出: False
  22. # 获取是否为年末
  23. print(ts.is_year_end)  # 输出: False
复制代码

时间戳的格式化输出
  1. ts = pd.Timestamp('2023-01-15 14:30:25.123456')
  2. # 使用strftime方法格式化输出
  3. print(ts.strftime('%Y-%m-%d %H:%M:%S'))  # 输出: 2023-01-15 14:30:25
  4. print(ts.strftime('%A, %B %d, %Y'))     # 输出: Sunday, January 15, 2023
  5. print(ts.strftime('%Y年%m月%d日 %H时%M分%S秒'))  # 输出: 2023年01月15日 14时30分25秒
  6. # 使用isoformat方法获取ISO格式
  7. print(ts.isoformat())  # 输出: 2023-01-15T14:30:25.123456
复制代码

时间序列的创建和操作

创建时间序列
  1. # 使用date_range创建日期范围
  2. dates = pd.date_range(start='2023-01-01', end='2023-01-10')
  3. print(dates)
  4. """
  5. 输出:
  6. DatetimeIndex(['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04',
  7.                '2023-01-05', '2023-01-06', '2023-01-07', '2023-01-08',
  8.                '2023-01-09', '2023-01-10'],
  9.               dtype='datetime64[ns]', freq='D')
  10. """
  11. # 指定频率
  12. dates_hourly = pd.date_range(start='2023-01-01', periods=24, freq='H')
  13. print(dates_hourly)
  14. """
  15. 输出:
  16. DatetimeIndex(['2023-01-01 00:00:00', '2023-01-01 01:00:00',
  17.                '2023-01-01 02:00:00', '2023-01-01 03:00:00',
  18.                '2023-01-01 04:00:00', '2023-01-01 05:00:00',
  19.                '2023-01-01 06:00:00', '2023-01-01 07:00:00',
  20.                '2023-01-01 08:00:00', '2023-01-01 09:00:00',
  21.                '2023-01-01 10:00:00', '2023-01-01 11:00:00',
  22.                '2023-01-01 12:00:00', '2023-01-01 13:00:00',
  23.                '2023-01-01 14:00:00', '2023-01-01 15:00:00',
  24.                '2023-01-01 16:00:00', '2023-01-01 17:00:00',
  25.                '2023-01-01 18:00:00', '2023-01-01 19:00:00',
  26.                '2023-01-01 20:00:00', '2023-01-01 21:00:00',
  27.                '2023-01-01 22:00:00', '2023-01-01 23:00:00'],
  28.               dtype='datetime64[ns]', freq='H')
  29. """
  30. # 创建带时间戳的Series
  31. import numpy as np
  32. ts_series = pd.Series(np.random.randn(10), index=pd.date_range('2023-01-01', periods=10, freq='D'))
  33. print(ts_series)
  34. """
  35. 输出:
  36. 2023-01-01    0.469112
  37. 2023-01-02   -0.282863
  38. 2023-01-03   -1.509059
  39. 2023-01-04   -1.135632
  40. 2023-01-05    1.212112
  41. 2023-01-06   -0.173215
  42. 2023-01-07    0.119209
  43. 2023-01-08   -1.044236
  44. 2023-01-09   -0.861849
  45. 2023-01-10   -2.104569
  46. Freq: D, dtype: float64
  47. """
复制代码

时间序列的索引和切片
  1. # 创建时间序列数据
  2. dates = pd.date_range('2023-01-01', periods=100, freq='D')
  3. ts = pd.Series(np.random.randn(100), index=dates)
  4. # 通过日期字符串索引
  5. print(ts['2023-01-15'])  # 获取特定日期的值
  6. # 切片操作
  7. print(ts['2023-01-15':'2023-01-20'])  # 获取日期范围内的值
  8. # 使用年份和月份索引
  9. print(ts['2023-01'])  # 获取2023年1月的所有数据
  10. print(ts['2023'])     # 获取2023年的所有数据
  11. # 使用truncate方法截取时间范围
  12. print(ts.truncate(before='2023-01-15', after='2023-01-20'))
复制代码

时间戳的计算和比较

时间差计算
  1. # 创建两个时间戳
  2. ts1 = pd.Timestamp('2023-01-15')
  3. ts2 = pd.Timestamp('2023-02-20')
  4. # 计算时间差
  5. delta = ts2 - ts1
  6. print(delta)
  7. # 输出: 36 days 00:00:00
  8. # 时间差的天数和秒数
  9. print(delta.days)      # 输出: 36
  10. print(delta.seconds)   # 输出: 0
  11. # 创建Timedelta对象
  12. td = pd.Timedelta(days=5, hours=3, minutes=30)
  13. print(td)
  14. # 输出: 5 days 03:30:00
  15. # 时间戳加减时间差
  16. ts3 = ts1 + td
  17. print(ts3)
  18. # 输出: 2023-01-20 03:30:00
  19. ts4 = ts2 - td
  20. print(ts4)
  21. # 输出: 2023-02-14 20:30:00
复制代码

时间戳的比较
  1. # 创建时间戳列表
  2. timestamps = [
  3.     pd.Timestamp('2023-01-15'),
  4.     pd.Timestamp('2023-02-20'),
  5.     pd.Timestamp('2023-03-10'),
  6.     pd.Timestamp('2022-12-25')
  7. ]
  8. # 找出最早和最晚的时间戳
  9. print(min(timestamps))  # 输出: 2022-12-25 00:00:00
  10. print(max(timestamps))  # 输出: 2023-03-10 00:00:00
  11. # 排序时间戳
  12. sorted_ts = sorted(timestamps)
  13. print(sorted_ts)
  14. """
  15. 输出:
  16. [Timestamp('2022-12-25 00:00:00'),
  17. Timestamp('2023-01-15 00:00:00'),
  18. Timestamp('2023-02-20 00:00:00'),
  19. Timestamp('2023-03-10 00:00:00')]
  20. """
  21. # 比较时间戳
  22. ts1 = pd.Timestamp('2023-01-15')
  23. ts2 = pd.Timestamp('2023-02-20')
  24. print(ts1 < ts2)  # 输出: True
  25. print(ts1 > ts2)  # 输出: False
  26. print(ts1 == ts1) # 输出: True
复制代码

时区处理

时区感知时间戳
  1. # 创建时区感知时间戳
  2. ts_utc = pd.Timestamp('2023-01-15 14:30:25', tz='UTC')
  3. print(ts_utc)
  4. # 输出: 2023-01-15 14:30:25+00:00
  5. # 创建带有时区的时间戳
  6. ts_ny = pd.Timestamp('2023-01-15 14:30:25', tz='America/New_York')
  7. print(ts_ny)
  8. # 输出: 2023-01-15 14:30:25-05:00
  9. # 获取时区信息
  10. print(ts_utc.tz)  # 输出: UTC
  11. print(ts_ny.tz)   # 输出: America/New_York
复制代码

时区转换
  1. # 创建UTC时间戳
  2. ts_utc = pd.Timestamp('2023-01-15 14:30:25', tz='UTC')
  3. # 转换为其他时区
  4. ts_ny = ts_utc.tz_convert('America/New_York')
  5. print(ts_ny)
  6. # 输出: 2023-01-15 09:30:25-05:00
  7. ts_tokyo = ts_utc.tz_convert('Asia/Tokyo')
  8. print(ts_tokyo)
  9. # 输出: 2023-01-15 23:30:25+09:00
  10. # 本地化无时区时间戳
  11. ts_naive = pd.Timestamp('2023-01-15 14:30:25')
  12. ts_localized = ts_naive.tz_localize('UTC')
  13. print(ts_localized)
  14. # 输出: 2023-01-15 14:30:25+00:00
  15. # 去除时区信息
  16. ts_naive_again = ts_localized.tz_convert(None)
  17. print(ts_naive_again)
  18. # 输出: 2023-01-15 14:30:25
复制代码

处理夏令时
  1. # 创建一个跨越夏令时变化的时间范围
  2. dates = pd.date_range('2023-03-11', '2023-03-13', tz='America/New_York', freq='H')
  3. print(dates)
  4. """
  5. 输出:
  6. DatetimeIndex(['2023-03-11 00:00:00-05:00', '2023-03-11 01:00:00-05:00',
  7.                '2023-03-11 03:00:00-04:00', '2023-03-11 04:00:00-04:00',
  8.                '2023-03-11 05:00:00-04:00', '2023-03-11 06:00:00-04:00',
  9.                '2023-03-11 07:00:00-04:00', '2023-03-11 08:00:00-04:00',
  10.                '2023-03-11 09:00:00-04:00', '2023-03-11 10:00:00-04:00',
  11.                '2023-03-11 11:00:00-04:00', '2023-03-11 12:00:00-04:00',
  12.                '2023-03-11 13:00:00-04:00', '2023-03-11 14:00:00-04:00',
  13.                '2023-03-11 15:00:00-04:00', '2023-03-11 16:00:00-04:00',
  14.                '2023-03-11 17:00:00-04:00', '2023-03-11 18:00:00-04:00',
  15.                '2023-03-11 19:00:00-04:00', '2023-03-11 20:00:00-04:00',
  16.                '2023-03-11 21:00:00-04:00', '2023-03-11 22:00:00-04:00',
  17.                '2023-03-11 23:00:00-04:00', '2023-03-12 00:00:00-04:00',
  18.                '2023-03-12 01:00:00-04:00', '2023-03-12 02:00:00-04:00',
  19.                '2023-03-12 03:00:00-04:00', '2023-03-12 04:00:00-04:00',
  20.                '2023-03-12 05:00:00-04:00', '2023-03-12 06:00:00-04:00',
  21.                '2023-03-12 07:00:00-04:00', '2023-03-12 08:00:00-04:00',
  22.                '2023-03-12 09:00:00-04:00', '2023-03-12 10:00:00-04:00',
  23.                '2023-03-12 11:00:00-04:00', '2023-03-12 12:00:00-04:00',
  24.                '2023-03-12 13:00:00-04:00', '2023-03-12 14:00:00-04:00',
  25.                '2023-03-12 15:00:00-04:00', '2023-03-12 16:00:00-04:00',
  26.                '2023-03-12 17:00:00-04:00', '2023-03-12 18:00:00-04:00',
  27.                '2023-03-12 19:00:00-04:00', '2023-03-12 20:00:00-04:00',
  28.                '2023-03-12 21:00:00-04:00', '2023-03-12 22:00:00-04:00',
  29.                '2023-03-12 23:00:00-04:00', '2023-03-13 00:00:00-04:00',
  30.                '2023-03-13 01:00:00-04:00', '2023-03-13 02:00:00-04:00',
  31.                '2023-03-13 03:00:00-04:00', '2023-03-13 04:00:00-04:00',
  32.                '2023-03-13 05:00:00-04:00', '2023-03-13 06:00:00-04:00',
  33.                '2023-03-13 07:00:00-04:00', '2023-03-13 08:00:00-04:00'],
  34.               dtype='datetime64[ns, America/New_York]', freq='H')
  35. """
  36. # 注意:在2023-03-11 02:00:00,时钟从01:59:59直接跳到03:00:00(夏令时开始)
复制代码

时间重采样和频率转换

降采样(将高频数据转换为低频数据)
  1. # 创建高频时间序列数据
  2. dates = pd.date_range('2023-01-01', periods=1000, freq='H')
  3. ts = pd.Series(np.random.randn(1000), index=dates)
  4. # 降采样为日数据,计算每日平均值
  5. daily_mean = ts.resample('D').mean()
  6. print(daily_mean.head())
  7. # 降采样为周数据,计算每周总和
  8. weekly_sum = ts.resample('W').sum()
  9. print(weekly_sum.head())
  10. # 降采样为月数据,计算每月最大值
  11. monthly_max = ts.resample('M').max()
  12. print(monthly_max.head())
  13. # 使用OHLC(开高低收)重采样
  14. ohlc = ts.resample('D').ohlc()
  15. print(ohlc.head())
复制代码

升采样(将低频数据转换为高频数据)
  1. # 创建低频时间序列数据
  2. dates = pd.date_range('2023-01-01', periods=10, freq='D')
  3. ts = pd.Series(np.random.randn(10), index=dates)
  4. # 升采样为小时数据,使用前向填充
  5. hourly_ffill = ts.resample('H').ffill()
  6. print(hourly_ffill.head(24))
  7. # 升采样为小时数据,使用后向填充
  8. hourly_bfill = ts.resample('H').bfill()
  9. print(hourly_bfill.head(24))
  10. # 升采样为小时数据,使用插值
  11. hourly_interpolate = ts.resample('H').interpolate()
  12. print(hourly_interpolate.head(24))
复制代码

自定义重采样规则
  1. # 创建时间序列数据
  2. dates = pd.date_range('2023-01-01', periods=100, freq='D')
  3. ts = pd.Series(np.random.randn(100), index=dates)
  4. # 每3天重采样一次
  5. three_day_mean = ts.resample('3D').mean()
  6. print(three_day_mean.head())
  7. # 每周周一重采样
  8. weekly_monday = ts.resample('W-MON').sum()
  9. print(weekly_monday.head())
  10. # 每月15号重采样
  11. monthly_15th = ts.resample('MS').sum()  # MS表示月初
  12. print(monthly_15th.head())
  13. # 使用自定义函数进行重采样
  14. custom_resample = ts.resample('M').apply(lambda x: x.max() - x.min())
  15. print(custom_resample.head())
复制代码

时间窗口操作

滚动窗口计算
  1. # 创建时间序列数据
  2. dates = pd.date_range('2023-01-01', periods=100, freq='D')
  3. ts = pd.Series(np.random.randn(100), index=dates)
  4. # 计算3天滚动平均值
  5. rolling_mean_3d = ts.rolling(window=3).mean()
  6. print(rolling_mean_3d.head())
  7. # 计算7天滚动标准差
  8. rolling_std_7d = ts.rolling(window=7).std()
  9. print(rolling_std_7d.head())
  10. # 计算30天滚动最大值
  11. rolling_max_30d = ts.rolling(window=30).max()
  12. print(rolling_max_30d.head())
  13. # 计算滚动相关系数
  14. ts2 = pd.Series(np.random.randn(100), index=dates)
  15. rolling_corr = ts.rolling(window=10).corr(ts2)
  16. print(rolling_corr.head())
复制代码

扩展窗口计算
  1. # 创建时间序列数据
  2. dates = pd.date_range('2023-01-01', periods=100, freq='D')
  3. ts = pd.Series(np.random.randn(100), index=dates)
  4. # 计算扩展窗口平均值(从开始到当前点的所有数据)
  5. expanding_mean = ts.expanding().mean()
  6. print(expanding_mean.head())
  7. # 计算扩展窗口最大值
  8. expanding_max = ts.expanding().max()
  9. print(expanding_max.head())
  10. # 计算扩展窗口累积和
  11. expanding_sum = ts.expanding().sum()
  12. print(expanding_sum.head())
复制代码

指数加权窗口
  1. # 创建时间序列数据
  2. dates = pd.date_range('2023-01-01', periods=100, freq='D')
  3. ts = pd.Series(np.random.randn(100), index=dates)
  4. # 计算指数加权移动平均(span=10)
  5. ewm_span = ts.ewm(span=10).mean()
  6. print(ewm_span.head())
  7. # 计算指数加权移动平均(halflife=5)
  8. ewm_halflife = ts.ewm(halflife=5).mean()
  9. print(ewm_halflife.head())
  10. # 计算指数加权移动标准差
  11. ewm_std = ts.ewm(span=10).std()
  12. print(ewm_std.head())
复制代码

时间戳与字符串的转换

将字符串解析为时间戳
  1. # 使用to_datetime将字符串转换为时间戳
  2. date_str = '2023-01-15'
  3. ts = pd.to_datetime(date_str)
  4. print(ts)
  5. # 输出: 2023-01-15 00:00:00
  6. # 解析不同格式的日期字符串
  7. date_str1 = '15/01/2023'
  8. date_str2 = 'January 15, 2023'
  9. date_str3 = '20230115'
  10. ts1 = pd.to_datetime(date_str1, format='%d/%m/%Y')
  11. ts2 = pd.to_datetime(date_str2)
  12. ts3 = pd.to_datetime(date_str3, format='%Y%m%d')
  13. print(ts1)  # 输出: 2023-01-15 00:00:00
  14. print(ts2)  # 输出: 2023-01-15 00:00:00
  15. print(ts3)  # 输出: 2023-01-15 00:00:00
  16. # 批量转换字符串列表
  17. date_strings = ['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04']
  18. timestamps = pd.to_datetime(date_strings)
  19. print(timestamps)
  20. """
  21. 输出:
  22. DatetimeIndex(['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04'], dtype='datetime64[ns]', freq=None)
  23. """
  24. # 处理无效日期
  25. invalid_dates = ['2023-01-01', '2023-02-30', '2023-03-01']  # 2月没有30号
  26. # 使用errors='coerce'将无效日期转换为NaT
  27. valid_dates = pd.to_datetime(invalid_dates, errors='coerce')
  28. print(valid_dates)
  29. """
  30. 输出:
  31. DatetimeIndex(['2023-01-01', 'NaT', '2023-03-01'], dtype='datetime64[ns]', freq=None)
  32. """
复制代码

将时间戳格式化为字符串
  1. # 创建时间戳
  2. ts = pd.Timestamp('2023-01-15 14:30:25')
  3. # 使用strftime方法格式化
  4. date_str = ts.strftime('%Y-%m-%d %H:%M:%S')
  5. print(date_str)
  6. # 输出: 2023-01-15 14:30:25
  7. # 批量格式化时间戳
  8. timestamps = pd.date_range('2023-01-01', periods=5, freq='D')
  9. date_strings = timestamps.strftime('%Y/%m/%d')
  10. print(date_strings)
  11. """
  12. 输出:
  13. Index(['2023/01/01', '2023/01/02', '2023/01/03', '2023/01/04', '2023/01/05'], dtype='object')
  14. """
  15. # 在DataFrame中格式化日期
  16. df = pd.DataFrame({
  17.     'date': pd.date_range('2023-01-01', periods=5, freq='D'),
  18.     'value': [1, 2, 3, 4, 5]
  19. })
  20. # 添加格式化后的日期字符串列
  21. df['date_str'] = df['date'].dt.strftime('%Y年%m月%d日')
  22. print(df)
  23. """
  24. 输出:
  25.         date  value      date_str
  26. 0 2023-01-01      1  2023年01月01日
  27. 1 2023-01-02      2  2023年01月02日
  28. 2 2023-01-03      3  2023年01月03日
  29. 3 2023-01-04      4  2023年01月04日
  30. 4 2023-01-05      5  2023年01月05日
  31. """
复制代码

实际应用案例

案例1:股票数据分析
  1. import pandas as pd
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. # 创建模拟股票数据
  5. np.random.seed(42)
  6. date_rng = pd.date_range(start='2022-01-01', end='2022-12-31', freq='D')
  7. prices = np.cumsum(np.random.randn(len(date_rng)) * 0.5 + 100)
  8. volumes = np.random.randint(10000, 100000, size=len(date_rng))
  9. # 创建DataFrame
  10. stock_df = pd.DataFrame({
  11.     'date': date_rng,
  12.     'price': prices,
  13.     'volume': volumes
  14. }).set_index('date')
  15. # 只保留工作日的数据
  16. stock_df = stock_df[stock_df.index.dayofweek < 5]
  17. print(stock_df.head())
  18. # 计算移动平均
  19. stock_df['ma_5'] = stock_df['price'].rolling(window=5).mean()
  20. stock_df['ma_20'] = stock_df['price'].rolling(window=20).mean()
  21. stock_df['ma_60'] = stock_df['price'].rolling(window=60).mean()
  22. # 计算日收益率
  23. stock_df['daily_return'] = stock_df['price'].pct_change()
  24. # 计算波动率(20日滚动标准差)
  25. stock_df['volatility'] = stock_df['daily_return'].rolling(window=20).std() * np.sqrt(252)
  26. # 绘制价格和移动平均线
  27. plt.figure(figsize=(12, 6))
  28. plt.plot(stock_df.index, stock_df['price'], label='Price')
  29. plt.plot(stock_df.index, stock_df['ma_5'], label='MA 5')
  30. plt.plot(stock_df.index, stock_df['ma_20'], label='MA 20')
  31. plt.plot(stock_df.index, stock_df['ma_60'], label='MA 60')
  32. plt.title('Stock Price with Moving Averages')
  33. plt.xlabel('Date')
  34. plt.ylabel('Price')
  35. plt.legend()
  36. plt.grid(True)
  37. plt.show()
  38. # 绘制波动率
  39. plt.figure(figsize=(12, 6))
  40. plt.plot(stock_df.index, stock_df['volatility'])
  41. plt.title('Stock Volatility (20-day rolling annualized)')
  42. plt.xlabel('Date')
  43. plt.ylabel('Volatility')
  44. plt.grid(True)
  45. plt.show()
  46. # 按月重采样数据
  47. monthly_data = stock_df.resample('M').agg({
  48.     'price': 'last',
  49.     'volume': 'sum',
  50.     'daily_return': 'mean',
  51.     'volatility': 'mean'
  52. })
  53. print(monthly_data.head())
复制代码

案例2:网站流量分析
  1. import pandas as pd
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. # 创建模拟网站访问数据
  5. np.random.seed(42)
  6. date_rng = pd.date_range(start='2023-01-01', end='2023-01-31', freq='H')
  7. visitors = np.random.randint(50, 500, size=len(date_rng))
  8. # 添加周末效应(周末访问量更高)
  9. weekend_effect = np.where(date_rng.dayofweek >= 5, 1.5, 1.0)
  10. visitors = (visitors * weekend_effect).astype(int)
  11. # 添加日内效应(白天访问量更高)
  12. hour_effect = np.sin(np.pi * (date_rng.hour - 6) / 12) * 0.5 + 1.0
  13. hour_effect = np.where(hour_effect < 0.5, 0.5, hour_effect)
  14. visitors = (visitors * hour_effect).astype(int)
  15. # 创建DataFrame
  16. traffic_df = pd.DataFrame({
  17.     'datetime': date_rng,
  18.     'visitors': visitors
  19. }).set_index('datetime')
  20. print(traffic_df.head())
  21. # 按天重采样
  22. daily_traffic = traffic_df.resample('D').sum()
  23. print(daily_traffic.head())
  24. # 按周重采样
  25. weekly_traffic = traffic_df.resample('W').sum()
  26. print(weekly_traffic.head())
  27. # 按小时分析平均访问量
  28. hourly_pattern = traffic_df.groupby(traffic_df.index.hour).mean()
  29. print(hourly_pattern.head())
  30. # 绘制每日访问量
  31. plt.figure(figsize=(12, 6))
  32. daily_traffic['visitors'].plot()
  33. plt.title('Daily Website Traffic')
  34. plt.xlabel('Date')
  35. plt.ylabel('Visitors')
  36. plt.grid(True)
  37. plt.show()
  38. # 绘制小时访问模式
  39. plt.figure(figsize=(12, 6))
  40. hourly_pattern['visitors'].plot()
  41. plt.title('Average Hourly Traffic Pattern')
  42. plt.xlabel('Hour of Day')
  43. plt.ylabel('Average Visitors')
  44. plt.grid(True)
  45. plt.xticks(range(24))
  46. plt.show()
  47. # 检测异常访问量(使用Z-score)
  48. daily_traffic['z_score'] = (daily_traffic['visitors'] - daily_traffic['visitors'].mean()) / daily_traffic['visitors'].std()
  49. anomalies = daily_traffic[abs(daily_traffic['z_score']) > 2]
  50. print("Anomalous days:")
  51. print(anomalies)
  52. # 绘制异常访问量
  53. plt.figure(figsize=(12, 6))
  54. daily_traffic['visitors'].plot(label='Daily Visitors')
  55. plt.scatter(anomalies.index, anomalies['visitors'], color='red', label='Anomalies')
  56. plt.title('Daily Website Traffic with Anomalies')
  57. plt.xlabel('Date')
  58. plt.ylabel('Visitors')
  59. plt.legend()
  60. plt.grid(True)
  61. plt.show()
复制代码

案例3:传感器数据分析
  1. import pandas as pd
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. # 创建模拟传感器数据
  5. np.random.seed(42)
  6. date_rng = pd.date_range(start='2023-01-01', periods=1440, freq='min')  # 24小时的数据
  7. temperature = 20 + 5 * np.sin(2 * np.pi * np.arange(1440) / (24 * 60)) + np.random.normal(0, 0.5, 1440)
  8. humidity = 50 + 20 * np.sin(2 * np.pi * np.arange(1440) / (24 * 60) + np.pi/4) + np.random.normal(0, 2, 1440)
  9. # 创建DataFrame
  10. sensor_df = pd.DataFrame({
  11.     'timestamp': date_rng,
  12.     'temperature': temperature,
  13.     'humidity': humidity
  14. }).set_index('timestamp')
  15. print(sensor_df.head())
  16. # 检测并处理异常值
  17. def detect_outliers(series, window=10, sigma=3):
  18.     rolling_mean = series.rolling(window=window).mean()
  19.     rolling_std = series.rolling(window=window).std()
  20.     z_scores = (series - rolling_mean) / rolling_std
  21.     return np.abs(z_scores) > sigma
  22. # 标记异常值
  23. sensor_df['temp_outlier'] = detect_outliers(sensor_df['temperature'])
  24. sensor_df['humidity_outlier'] = detect_outliers(sensor_df['humidity'])
  25. # 替换异常值为滚动平均值
  26. sensor_df.loc[sensor_df['temp_outlier'], 'temperature'] = sensor_df['temperature'].rolling(window=10).mean()
  27. sensor_df.loc[sensor_df['humidity_outlier'], 'humidity'] = sensor_df['humidity'].rolling(window=10).mean()
  28. # 按小时重采样
  29. hourly_data = sensor_df.resample('H').agg({
  30.     'temperature': ['mean', 'min', 'max'],
  31.     'humidity': ['mean', 'min', 'max']
  32. })
  33. print(hourly_data.head())
  34. # 计算温湿度相关性
  35. correlation = sensor_df['temperature'].corr(sensor_df['humidity'])
  36. print(f"Temperature-Humidity Correlation: {correlation:.2f}")
  37. # 绘制温度数据
  38. plt.figure(figsize=(12, 6))
  39. sensor_df['temperature'].plot(label='Temperature')
  40. plt.scatter(sensor_df[sensor_df['temp_outlier']].index,
  41.             sensor_df[sensor_df['temp_outlier']]['temperature'],
  42.             color='red', label='Outliers')
  43. plt.title('Temperature Readings with Outliers')
  44. plt.xlabel('Time')
  45. plt.ylabel('Temperature (°C)')
  46. plt.legend()
  47. plt.grid(True)
  48. plt.show()
  49. # 绘制湿度数据
  50. plt.figure(figsize=(12, 6))
  51. sensor_df['humidity'].plot(label='Humidity')
  52. plt.scatter(sensor_df[sensor_df['humidity_outlier']].index,
  53.             sensor_df[sensor_df['humidity_outlier']]['humidity'],
  54.             color='red', label='Outliers')
  55. plt.title('Humidity Readings with Outliers')
  56. plt.xlabel('Time')
  57. plt.ylabel('Humidity (%)')
  58. plt.legend()
  59. plt.grid(True)
  60. plt.show()
  61. # 绘制温湿度散点图
  62. plt.figure(figsize=(10, 6))
  63. plt.scatter(sensor_df['temperature'], sensor_df['humidity'], alpha=0.5)
  64. plt.title('Temperature vs Humidity')
  65. plt.xlabel('Temperature (°C)')
  66. plt.ylabel('Humidity (%)')
  67. plt.grid(True)
  68. plt.show()
复制代码

性能优化技巧

使用适当的数据类型
  1. import pandas as pd
  2. import numpy as np
  3. # 创建大数据集
  4. dates = pd.date_range('2000-01-01', periods=1000000, freq='H')
  5. values = np.random.randn(1000000)
  6. df = pd.DataFrame({'timestamp': dates, 'value': values})
  7. # 检查内存使用
  8. print(f"Memory usage with datetime64[ns]: {df.memory_usage(deep=True).sum() / 1024**2:.2f} MB")
  9. # 如果时间戳精度不需要纳秒级别,可以转换为秒级精度
  10. df['timestamp_sec'] = df['timestamp'].astype('datetime64[s]')
  11. print(f"Memory usage with datetime64[s]: {df.memory_usage(deep=True).sum() / 1024**2:.2f} MB")
  12. # 对于周期性数据,可以考虑使用周期数据类型
  13. df['period'] = df['timestamp'].dt.to_period('H')
  14. print(f"Memory usage with period: {df.memory_usage(deep=True).sum() / 1024**2:.2f} MB")
复制代码

使用向量化操作
  1. import pandas as pd
  2. import numpy as np
  3. import time
  4. # 创建大数据集
  5. dates = pd.date_range('2000-01-01', periods=1000000, freq='H')
  6. df = pd.DataFrame({'timestamp': dates, 'value': np.random.randn(1000000)})
  7. # 方法1:使用循环提取小时信息(慢)
  8. start_time = time.time()
  9. hours_loop = []
  10. for ts in df['timestamp']:
  11.     hours_loop.append(ts.hour)
  12. print(f"Loop method: {time.time() - start_time:.4f} seconds")
  13. # 方法2:使用向量化操作(快)
  14. start_time = time.time()
  15. hours_vectorized = df['timestamp'].dt.hour
  16. print(f"Vectorized method: {time.time() - start_time:.4f} seconds")
  17. # 验证结果是否相同
  18. print(f"Results are equal: {np.array_equal(hours_loop, hours_vectorized)}")
复制代码

使用分类数据类型处理重复时间戳
  1. import pandas as pd
  2. import numpy as np
  3. # 创建带有重复时间戳的数据集
  4. dates = pd.date_range('2000-01-01', periods=1000, freq='D')
  5. repeated_dates = np.random.choice(dates, 100000)
  6. df = pd.DataFrame({'timestamp': repeated_dates, 'value': np.random.randn(100000)})
  7. # 检查内存使用
  8. print(f"Memory usage before converting to category: {df.memory_usage(deep=True).sum() / 1024**2:.2f} MB")
  9. # 将时间戳转换为分类类型
  10. df['timestamp_cat'] = df['timestamp'].astype('category')
  11. print(f"Memory usage after converting to category: {df.memory_usage(deep=True).sum() / 1024**2:.2f} MB")
复制代码

使用高效的时间范围查询
  1. import pandas as pd
  2. import numpy as np
  3. import time
  4. # 创建大数据集
  5. dates = pd.date_range('2000-01-01', periods=1000000, freq='H')
  6. df = pd.DataFrame({'timestamp': dates, 'value': np.random.randn(1000000)}).set_index('timestamp')
  7. # 方法1:使用布尔索引(慢)
  8. start_time = time.time()
  9. result1 = df.loc[(df.index >= '2005-01-01') & (df.index <= '2005-01-31')]
  10. print(f"Boolean indexing method: {time.time() - start_time:.4f} seconds")
  11. # 方法2:使用切片(快)
  12. start_time = time.time()
  13. result2 = df.loc['2005-01-01':'2005-01-31']
  14. print(f"Slicing method: {time.time() - start_time:.4f} seconds")
  15. # 验证结果是否相同
  16. print(f"Results are equal: {result1.equals(result2)}")
复制代码

使用并行处理加速时间序列操作
  1. import pandas as pd
  2. import numpy as np
  3. from multiprocessing import Pool, cpu_count
  4. import time
  5. # 创建大数据集
  6. dates = pd.date_range('2000-01-01', periods=1000000, freq='H')
  7. df = pd.DataFrame({'timestamp': dates, 'value': np.random.randn(1000000)})
  8. # 定义一个处理函数
  9. def process_chunk(chunk):
  10.     chunk['hour'] = chunk['timestamp'].dt.hour
  11.     chunk['day_of_week'] = chunk['timestamp'].dt.dayofweek
  12.     chunk['rolling_mean'] = chunk['value'].rolling(window=24).mean()
  13.     return chunk
  14. # 方法1:顺序处理
  15. start_time = time.time()
  16. result_sequential = process_chunk(df)
  17. print(f"Sequential processing: {time.time() - start_time:.4f} seconds")
  18. # 方法2:并行处理
  19. def parallel_processing(df, n_chunks=4):
  20.     chunks = np.array_split(df, n_chunks)
  21.    
  22.     with Pool(cpu_count()) as pool:
  23.         results = pool.map(process_chunk, chunks)
  24.    
  25.     return pd.concat(results)
  26. start_time = time.time()
  27. result_parallel = parallel_processing(df)
  28. print(f"Parallel processing: {time.time() - start_time:.4f} seconds")
  29. # 验证结果是否相同
  30. print(f"Results are equal: {result_sequential.equals(result_parallel)}")
复制代码

总结与进阶学习资源

本文详细介绍了Pandas时间戳的基础知识和高级应用技巧,包括时间戳的创建、属性访问、时间序列操作、时区处理、时间重采样、窗口操作以及时间戳与字符串的转换等内容。通过实际案例,我们展示了如何将这些技巧应用于股票数据分析、网站流量分析和传感器数据分析等场景。最后,我们还分享了一些性能优化技巧,帮助你在处理大规模时间数据时提高效率。

要进一步提升你的时间数据处理能力,以下是一些推荐的学习资源:

1. 官方文档:Pandas时间序列/日期功能文档:https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.htmlPandas时间戳API参考:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Timestamp.html
2. Pandas时间序列/日期功能文档:https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html
3. Pandas时间戳API参考:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Timestamp.html
4. 书籍:《Python for Data Analysis》by Wes McKinney (Pandas的创始人)《Pandas Cookbook》by Theodore Petrou《Mastering Pandas》by Femi Anthony
5. 《Python for Data Analysis》by Wes McKinney (Pandas的创始人)
6. 《Pandas Cookbook》by Theodore Petrou
7. 《Mastering Pandas》by Femi Anthony
8. 在线课程:DataCamp的”Pandas Time Series Analysis”课程Coursera的”Applied Data Science with Python”系列课程Udemy的”Pandas for Data Analysis”课程
9. DataCamp的”Pandas Time Series Analysis”课程
10. Coursera的”Applied Data Science with Python”系列课程
11. Udemy的”Pandas for Data Analysis”课程
12. 博客和教程:Real Python上的”Pandas Time Series Examples”教程Towards Data Science上的时间序列分析文章Machine Learning Mastery上的时间序列预测教程
13. Real Python上的”Pandas Time Series Examples”教程
14. Towards Data Science上的时间序列分析文章
15. Machine Learning Mastery上的时间序列预测教程
16. 实践项目:尝试分析真实的时间序列数据集,如Kaggle上的股票价格、天气数据或网站流量数据构建一个时间序列预测模型,如ARIMA、Prophet或LSTM创建一个交互式的时间序列可视化仪表板
17. 尝试分析真实的时间序列数据集,如Kaggle上的股票价格、天气数据或网站流量数据
18. 构建一个时间序列预测模型,如ARIMA、Prophet或LSTM
19. 创建一个交互式的时间序列可视化仪表板

官方文档:

• Pandas时间序列/日期功能文档:https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html
• Pandas时间戳API参考:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Timestamp.html

书籍:

• 《Python for Data Analysis》by Wes McKinney (Pandas的创始人)
• 《Pandas Cookbook》by Theodore Petrou
• 《Mastering Pandas》by Femi Anthony

在线课程:

• DataCamp的”Pandas Time Series Analysis”课程
• Coursera的”Applied Data Science with Python”系列课程
• Udemy的”Pandas for Data Analysis”课程

博客和教程:

• Real Python上的”Pandas Time Series Examples”教程
• Towards Data Science上的时间序列分析文章
• Machine Learning Mastery上的时间序列预测教程

实践项目:

• 尝试分析真实的时间序列数据集,如Kaggle上的股票价格、天气数据或网站流量数据
• 构建一个时间序列预测模型,如ARIMA、Prophet或LSTM
• 创建一个交互式的时间序列可视化仪表板

通过不断实践和学习,你将能够熟练掌握Pandas时间戳的各种技巧,并在数据分析项目中游刃有余地处理时间数据,提升你的数据分析能力。
「七転び八起き(ななころびやおき)」
回复

使用道具 举报

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

本版积分规则