时间序列:日期范围、频率和位移

11.3 日期范围、频率和位移

pandas的通用时间序列是不规则的,即时间序列的频率不是固定的。在处理固定频率的场景,例如每日的,每月的或每几分钟时,pandas有一套标准的时间序列频率和工具用于重新采样、推断频率以及生成固定频率的数据范围。例如使用resample方法将样本时间序列转换为固定的每日频率数据:

dates = [datetime(2011, 1, 2), datetime(2011, 1, 5),
         datetime(2011, 1, 7), datetime(2011, 1, 8),
         datetime(2011, 1, 10), datetime(2011, 1, 12)]
ts = pd.Series(np.random.randn(6), index=dates)
ts
2011-01-02   -0.763339
2011-01-05   -0.596903
2011-01-07    0.081843
2011-01-08    0.500183
2011-01-10   -0.369707
2011-01-12    0.641366
dtype: float64

resampler=ts.resample('D')           # D 被解释为每日频率。
resampler
<pandas.core.resample.DatetimeIndexResampler object at 0x000002177147FBC8>

在频率之间转换,又称为重新采样。这里只是展示如何使用基础频率和其倍数

11.3.1 生成日期范围

就是pandas.date_range ,用于根据特定频率生成指定长度的DatetimeIndex:

index = pd.date_range('2020-7-1','20200714')
index
DatetimeIndex(['2020-07-01', '2020-07-02', '2020-07-03', '2020-07-04',
               '2020-07-05', '2020-07-06', '2020-07-07', '2020-07-08',
               '2020-07-09', '2020-07-10', '2020-07-11', '2020-07-12',
               '2020-07-13', '2020-07-14'],
              dtype='datetime64[ns]', freq='D')
              
pd.date_range(start='2012-04-01', periods=2)         # date_range生成的是每日的时间戳,可用仅传递一个起始或结尾日期和一个范围
DatetimeIndex(['2012-04-01', '2012-04-02'], dtype='datetime64[ns]', freq='D')

pd.date_range(end='2012-06-01', periods=2)
DatetimeIndex(['2012-05-31', '2012-06-01'], dtype='datetime64[ns]', freq='D')

# 开始日期和结束日期严格定义了生成日期索引的边界。例如需要一个包含每月最后业务日期的时间索引,可以使用BM频率,只有范围内的日期会包括
pd.date_range('2000-01-01', '2000-12-01', freq='BM')
DatetimeIndex(['2000-01-31', '2000-02-29', '2000-03-31', '2000-04-28',   # 每月的最后一个工作日
               '2000-05-31', '2000-06-30', '2000-07-31', '2000-08-31',
               '2000-09-29', '2000-10-31', '2000-11-30'],
              dtype='datetime64[ns]', freq='BM')

在这里插入图片描述
在这里插入图片描述
讲究。。。

默认情况下,date_rane保留开始或结束时间戳的时间(如果有的话):

pd.date_range('2012-05-02 12:56:31', periods=5)
DatetimeIndex(['2012-05-02 12:56:31', '2012-05-03 12:56:31',
               '2012-05-04 12:56:31', '2012-05-05 12:56:31',
               '2012-05-06 12:56:31'],
              dtype='datetime64[ns]', freq='D')

# 想获得包含时间信息的开始日期或结束日期,但是你想要生成的是标准化为零点的时间戳,使用normalize选项。
pd.date_range('2012-05-02 12:56:31', periods=5, normalize=True) 
DatetimeIndex(['2012-05-02', '2012-05-03', '2012-05-04', '2012-05-05',
               '2012-05-06'],         # 将开始/结束日期标准化为零点,然后在生成日期。
              dtype='datetime64[ns]', freq='D')

11.3.2 频率和日期偏置

pandas中的频率是由基础频率和倍数组成 。基础频率就是 M D这些。对于每个基础频率,都有一个对象可用被用于定义日期偏置。例如每小时的频率可以使用Hour 类来表示

from pandas.tseries.offsets import Hour, Minute
hour = Hour()
hour
<Hour>

four_hour=Hour(4)
four_hour
<4 * Hours>

pd.date_range('2000-01-01', '2000-01-03 23:59', freq='4h')       # 但是对于大多数不用显示的创建这些对象,而是使用
DatetimeIndex(['2000-01-01 00:00:00', '2000-01-01 04:00:00',  # 字符串别名,4H,在基础索引前放一个整数就表示倍数。
               '2000-01-01 08:00:00', '2000-01-01 12:00:00',
               '2000-01-01 16:00:00', '2000-01-01 20:00:00',
               '2000-01-02 00:00:00', '2000-01-02 04:00:00',
               '2000-01-02 08:00:00', '2000-01-02 12:00:00',
               '2000-01-02 16:00:00', '2000-01-02 20:00:00',
               '2000-01-03 00:00:00', '2000-01-03 04:00:00',
               '2000-01-03 08:00:00', '2000-01-03 12:00:00',
               '2000-01-03 16:00:00', '2000-01-03 20:00:00'],
              dtype='datetime64[ns]', freq='4H')

Hour(2) + Minute(30)          # 多个偏好设置可以进行加法联合
<150 * Minutes>

pd.date_range('2000-01-01', periods=10, freq='1h30min')          # 还可以传递频率字符串,可以有效的转换为同等的表达式。
DatetimeIndex(['2000-01-01 00:00:00', '2000-01-01 01:30:00',
               '2000-01-01 03:00:00', '2000-01-01 04:30:00',
               '2000-01-01 06:00:00', '2000-01-01 07:30:00',
               '2000-01-01 09:00:00', '2000-01-01 10:30:00',
               '2000-01-01 12:00:00', '2000-01-01 13:30:00'],
              dtype='datetime64[ns]', freq='90T')

有些频率描述点是不均匀的,例如M BM 却决于当月的天数,这些日期称为锚定偏置量

11.3.2.1 月中某星期的日期
rng = pd.date_range('2012-01-01', '2012-09-01', freq='WOM-3FRI')   # 每月第三个星期五
list(rng)
[Timestamp('2012-01-20 00:00:00', freq='WOM-3FRI'),
 Timestamp('2012-02-17 00:00:00', freq='WOM-3FRI'),
 Timestamp('2012-03-16 00:00:00', freq='WOM-3FRI'),
 Timestamp('2012-04-20 00:00:00', freq='WOM-3FRI'),
 Timestamp('2012-05-18 00:00:00', freq='WOM-3FRI'),
 Timestamp('2012-06-15 00:00:00', freq='WOM-3FRI'),
 Timestamp('2012-07-20 00:00:00', freq='WOM-3FRI'),
 Timestamp('2012-08-17 00:00:00', freq='WOM-3FRI')]

11.3.3 位移(前向和后向)日期

位移是指将日期按时间向后向前移动。series and dateframe都有一个shift 方法来进行简单的前向和后向位移,而不改变索引:

ts = pd.Series(np.random.randn(4),
               index=pd.date_range('1/1/2000', periods=4, freq='M'))
ts
2000-01-31    0.239816
2000-02-29   -0.742286
2000-03-31   -0.237450
2000-04-30    0.375140
Freq: M, dtype: float64

ts.shift(2)
2000-01-31         NaN              # 这个是后移吧。。。
2000-02-29         NaN
2000-03-31    0.239816
2000-04-30   -0.742286
Freq: M, dtype: float64

ts.shift(-2)
2000-01-31   -0.23745
2000-02-29    0.37514        # 缺失位置就不上缺失值
2000-03-31        NaN
2000-04-30        NaN
Freq: M, dtype: float64

ts / ts.shift(1) - 1               # shift常用于计算时间序列或dataframe多列时间序列的百分比变化。

ts.shift(2, freq='M')    # 如果频率是已知的,可以传递给shift来推移时间戳
2000-03-31    0.239816
2000-04-30   -0.742286
2000-05-31   -0.237450
2000-06-30    0.375140
Freq: M, dtype: float64

ts.shift(3, freq='D')                 # 这些都可以,这里的T是分钟
ts.shift(1, freq='90T')
11.3.3.1 使用偏置进行位移日期

pandas日期偏置也可以使用datetiem or Timestamp 对象完成。

from pandas.tseries.offsets import Day, MonthEnd
now = datetime(2011, 11, 17)
now + 3 * Day()
Timestamp('2011-11-20 00:00:00')

now+MonthEnd()                 # 添加一个锚定偏置量,比如MonthEnd,根据频率规则,第一个增量会将日期前滚到下一个日期
Timestamp('2011-11-30 00:00:00')

now+MonthEnd(2)                # 啥叫前滚到下一个日期。。。反正0 1 都是11-30
Timestamp('2011-12-31 00:00:00')

offset=MonthEnd()
offset.rollforward(now)
Timestamp('2011-11-30 00:00:00')              # 锚定偏置可以使用rollforward rollback分别显示的将日期前滚后滚

offset.rollback(now)
Timestamp('2011-10-31 00:00:00')

ts = pd.Series(np.random.randn(20),
               index=pd.date_range('1/15/2000', periods=20, freq='4d'))
ts.groupby(offset.rollforward).mean()             # 位移方法与groupby一起使用
2000-01-31    0.593707
2000-02-29    0.141409
2000-03-31    0.083633
dtype: float64

ts.resample('M').mean()            # 这个方法更简单,以后再讨论。。。
2000-01-31    0.593707
2000-02-29    0.141409
2000-03-31    0.083633
Freq: M, dtype: float64
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值