【python数据分析(17)】Pandas中时间序列处理(3)时间戳索引中date_range()方法及频率freq的变换

1. pd.date_range() 生成日期范围

通过上一个博客中的输出结果的内容中可以看到,最后的时间戳索引里面的freq = None,下面就可以开始对freq输出结果进行处理了,主要是调整.date_range() 中的参数

pd.date_range(start=None, end=None, periods=None, freq=‘D’, tz=None, normalize=False, name=None, closed=None, **kwargs)

start:开始时间
end:结束时间
periods:持续时间
freq:频率,默认天
normalize:时间参数值正则化到午夜时间戳
name:索引对象名称
closed:默认为None的情况下,左闭右闭,left则左闭右开,right则左开右闭
pd.date_range()默认频率为日历日
pd.bdate_range()默认频率为工作日
tz:时区

1.1 部分参数的讲解
rng1 = pd.date_range('1/1/2017','1/10/2017', normalize=True)
rng2 = pd.date_range(start = '1/1/2017', periods = 10)
rng3 = pd.date_range(end = '1/30/2017 15:00:00', periods = 10)  
print(rng1)
print(type(rng1))
print(rng2)
print(rng3)

–> 输出的结果为:(rng1由于没有给出时分秒,即使标准化了也不显示出来;rng3添加了时分秒,是可以显示出来的,最后的freq也不再是None,变成了D,也就是day

DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',
               '2017-01-05', '2017-01-06', '2017-01-07', '2017-01-08',
               '2017-01-09', '2017-01-10'],
              dtype='datetime64[ns]', freq='D')
<class 'pandas.core.indexes.datetimes.DatetimeIndex'>
DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',
               '2017-01-05', '2017-01-06', '2017-01-07', '2017-01-08',
               '2017-01-09', '2017-01-10'],
              dtype='datetime64[ns]', freq='D')
DatetimeIndex(['2017-01-21 15:00:00', '2017-01-22 15:00:00',
               '2017-01-23 15:00:00', '2017-01-24 15:00:00',
               '2017-01-25 15:00:00', '2017-01-26 15:00:00',
               '2017-01-27 15:00:00', '2017-01-28 15:00:00',
               '2017-01-29 15:00:00', '2017-01-30 15:00:00'],
              dtype='datetime64[ns]', freq='D')

normalizename参数的使用

rng4 = pd.date_range(start = '1/1/2017 15:30', periods = 10, name = 'hello world!', normalize = True)
print(rng4)

–> 输出的结果为:(正则化处理之后原来后边的时间就不输出了,相当于直接取日期进行索引)

DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',
               '2017-01-05', '2017-01-06', '2017-01-07', '2017-01-08',
               '2017-01-09', '2017-01-10'],
              dtype='datetime64[ns]', name='hello world!', freq='D')

closed参数的使用

print(pd.date_range('20170101','20170104'))  
print(pd.date_range('20170101','20170104',closed = 'right'))
print(pd.date_range('20170101','20170104',closed = 'left'))

–> 输出的结果为:(第一个输出是有四个结果,其余的只有三个)

DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04'], dtype='datetime64[ns]', freq='D')
DatetimeIndex(['2017-01-02', '2017-01-03', '2017-01-04'], dtype='datetime64[ns]', freq='D')
DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03'], dtype='datetime64[ns]', freq='D')

.bdate_range() 工作日

print(pd.bdate_range('20200301','20200307'))

–> 输出的结果为:(3月1号是周日,3月7号是周六,注意最后的freq变成了B

DatetimeIndex(['2020-03-02', '2020-03-03', '2020-03-04', '2020-03-05',
               '2020-03-06'],
              dtype='datetime64[ns]', freq='B')

直接转化为list,元素为Timestamp

print(list(pd.date_range(start = '1/1/2017', periods = 10)))

–> 输出的结果为:

[Timestamp('2020-01-01 00:00:00', freq='D'),
Timestamp('2020-01-02 00:00:00', freq='D'),
Timestamp('2020-01-03 00:00:00', freq='D'), 
Timestamp('2020-01-04 00:00:00', freq='D'), 
Timestamp('2020-01-05 00:00:00', freq='D'), 
Timestamp('2020-01-06 00:00:00', freq='D'),
Timestamp('2020-01-07 00:00:00', freq='D'), 
Timestamp('2020-01-08 00:00:00', freq='D'), 
Timestamp('2020-01-09 00:00:00', freq='D'),
Timestamp('2020-01-10 00:00:00', freq='D')]

★★★★★★那么问题来了,之前的操作都是将日期字符串转化为日期索引,如何将这些列表中的索引重新转化为我们日常的字符串数据呢?

data = pd.date_range(start = '1/1/2020', periods = 10)
data_ = data.date.astype(str)
print(data_)
print(len(data_))

–> 输出的结果为:

['2020-01-01' '2020-01-02' '2020-01-03' '2020-01-04' '2020-01-05'
 '2020-01-06' '2020-01-07' '2020-01-08' '2020-01-09' '2020-01-10']
10

2. 核心参数freq讲解

全部内容通过思维导图归纳如下:
在这里插入图片描述

2.1 按每天中的时间频率进行输出
print(pd.date_range('2020/1/1','2020/1/3'),'\n')  # 默认freq = 'D':每日历日
print(pd.date_range('2020/1/1','2020/1/3', freq = 'B'),'\n')  # B:每工作日
print(pd.date_range('2020/1/1','2020/1/1', freq = 'H'),'\n')  # H:每小时
print(pd.date_range('2020/1/1 12:00','2020/1/1 12:10', freq = 'T'),'\n')  # T/MIN:每分
print(pd.date_range('2020/1/1 12:00:00','2020/1/1 12:00:10', freq = 'S'),'\n')  # S:每秒
print(pd.date_range('2020/1/1 12:00:00','2020/1/1 12:00:05', freq = 'L'),'\n')  # L:每毫秒(千分之一秒)
print(pd.date_range('2020/1/1 12:00:00','2020/1/1 12:00:01', freq = 'U'))  # U:每微秒(百万分之一秒)

–> 输出的结果为:

DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03'], dtype='datetime64[ns]', freq='D')

DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03'], dtype='datetime64[ns]', freq='B')

DatetimeIndex(['2020-01-01'], dtype='datetime64[ns]', freq='H')

DatetimeIndex(['2020-01-01 12:00:00', '2020-01-01 12:01:00',
               '2020-01-01 12:02:00', '2020-01-01 12:03:00',
               '2020-01-01 12:04:00', '2020-01-01 12:05:00',
               '2020-01-01 12:06:00', '2020-01-01 12:07:00',
               '2020-01-01 12:08:00', '2020-01-01 12:09:00',
               '2020-01-01 12:10:00'],
              dtype='datetime64[ns]', freq='T')
              
DatetimeIndex(['2020-01-01 12:00:00', '2020-01-01 12:00:01',
               '2020-01-01 12:00:02', '2020-01-01 12:00:03',
               '2020-01-01 12:00:04', '2020-01-01 12:00:05',
               '2020-01-01 12:00:06', '2020-01-01 12:00:07',
               '2020-01-01 12:00:08', '2020-01-01 12:00:09',
               '2020-01-01 12:00:10'],
              dtype='datetime64[ns]', freq='S')
              
DatetimeIndex([       '2020-01-01 12:00:00', '2020-01-01 12:00:00.001000',
               '2020-01-01 12:00:00.002000', '2020-01-01 12:00:00.003000',
               '2020-01-01 12:00:00.004000', '2020-01-01 12:00:00.005000',
               '2020-01-01 12:00:00.006000', '2020-01-01 12:00:00.007000',
               '2020-01-01 12:00:00.008000', '2020-01-01 12:00:00.009000',
               ...
               '2020-01-01 12:00:04.991000', '2020-01-01 12:00:04.992000',
               '2020-01-01 12:00:04.993000', '2020-01-01 12:00:04.994000',
               '2020-01-01 12:00:04.995000', '2020-01-01 12:00:04.996000',
               '2020-01-01 12:00:04.997000', '2020-01-01 12:00:04.998000',
               '2020-01-01 12:00:04.999000',        '2020-01-01 12:00:05'],
              dtype='datetime64[ns]', length=5001, freq='L')
              
DatetimeIndex([       '2020-01-01 12:00:00', '2020-01-01 12:00:00.000001',
               '2020-01-01 12:00:00.000002', '2020-01-01 12:00:00.000003',
               '2020-01-01 12:00:00.000004', '2020-01-01 12:00:00.000005',
               '2020-01-01 12:00:00.000006', '2020-01-01 12:00:00.000007',
               '2020-01-01 12:00:00.000008', '2020-01-01 12:00:00.000009',
               ...
               '2020-01-01 12:00:00.999991', '2020-01-01 12:00:00.999992',
               '2020-01-01 12:00:00.999993', '2020-01-01 12:00:00.999994',
               '2020-01-01 12:00:00.999995', '2020-01-01 12:00:00.999996',
               '2020-01-01 12:00:00.999997', '2020-01-01 12:00:00.999998',
               '2020-01-01 12:00:00.999999',        '2020-01-01 12:00:01'],
              dtype='datetime64[ns]', length=1000001, freq='U')
2.2 按照每周的时间进行输出

W-MON:从指定星期几开始算起,每周
星期几缩写:MON/TUE/WED/THU/FRI/SAT/SUN

print(pd.date_range('2020/1/1','2020/2/1', freq = 'W-MON'))  

–> 输出的结果为:

DatetimeIndex(['2020-01-06', '2020-01-13', '2020-01-20', '2020-01-27'], dtype='datetime64[ns]', freq='W-MON')
2.3 按照每月的时间进行输出

WOM-2MON:每月的第几个星期几开始算,这里是每月第二个星期一

print(pd.date_range('2020/1/1','2020/5/1', freq = 'WOM-2MON'))

–> 输出的结果为:

DatetimeIndex(['2020-01-13', '2020-02-10', '2020-03-09', '2020-04-13'], dtype='datetime64[ns]', freq='WOM-2MON')
2.4 按照日历日和工作日的时间进行输出

1) 最后的日历日

M:每月最后一个日历日
Q-月:指定月为季度末,每个季度末最后一月的最后一个日历日
A-月:每年指定月份的最后一个日历日
月缩写:JAN/FEB/MAR/APR/MAY/JUN/JUL/AUG/SEP/OCT/NOV/DEC
所以Q-月只有三种情况:1-4-7-10,2-5-8-11,3-6-9-12

print(pd.date_range('2020','2021', freq = 'M'))  
print(pd.date_range('2020','2021', freq = 'Q-DEC'))  
print(pd.date_range('2020','2021', freq = 'A-DEC')) 

–> 输出的结果为:

DatetimeIndex(['2020-01-31', '2020-02-29', '2020-03-31', '2020-04-30',
               '2020-05-31', '2020-06-30', '2020-07-31', '2020-08-31',
               '2020-09-30', '2020-10-31', '2020-11-30', '2020-12-31'],
              dtype='datetime64[ns]', freq='M')
DatetimeIndex(['2020-03-31', '2020-06-30', '2020-09-30', '2020-12-31'], dtype='datetime64[ns]', freq='Q-DEC')
DatetimeIndex(['2020-12-31'], dtype='datetime64[ns]', freq='A-DEC')

2) 最后的工作日

BM:每月最后一个工作日
BQ-月:指定月为季度末,每个季度末最后一月的最后一个工作日
BA-月:每年指定月份的最后一个工作日

print(pd.date_range('2020','2021', freq = 'BM'))  
print(pd.date_range('2020','2021', freq = 'BQ-DEC'))  
print(pd.date_range('2020','2021', freq = 'BA-DEC')) 

–> 输出的结果为:(注意和上面的输出进行对比)

DatetimeIndex(['2020-01-31', '2020-02-28', '2020-03-31', '2020-04-30',
               '2020-05-29', '2020-06-30', '2020-07-31', '2020-08-31',
               '2020-09-30', '2020-10-30', '2020-11-30', '2020-12-31'],
              dtype='datetime64[ns]', freq='BM')
DatetimeIndex(['2020-03-31', '2020-06-30', '2020-09-30', '2020-12-31'], dtype='datetime64[ns]', freq='BQ-DEC')
DatetimeIndex(['2020-12-31'], dtype='datetime64[ns]', freq='BA-DEC')

3) 第一个日历日

MS:每月第一个日历日
QS-月:指定月为季度末,每个季度末最后一月的第一个日历日
AS-月:每年指定月份的第一个日历日

print(pd.date_range('2020','2021', freq = 'MS'))  
print(pd.date_range('2020','2021', freq = 'QS-DEC'))  
print(pd.date_range('2020','2021', freq = 'AS-DEC'))

–> 输出的结果为:

DatetimeIndex(['2020-01-01', '2020-02-01', '2020-03-01', '2020-04-01',
               '2020-05-01', '2020-06-01', '2020-07-01', '2020-08-01',
               '2020-09-01', '2020-10-01', '2020-11-01', '2020-12-01',
               '2021-01-01'],
              dtype='datetime64[ns]', freq='MS')
DatetimeIndex(['2020-03-01', '2020-06-01', '2020-09-01', '2020-12-01'], dtype='datetime64[ns]', freq='QS-DEC')
DatetimeIndex(['2020-12-01'], dtype='datetime64[ns]', freq='AS-DEC')

4) 第一个工作日

BMS:每月第一个工作日
BQS-月:指定月为季度末,每个季度末最后一月的第一个工作日
BAS-月:每年指定月份的第一个工作日

print(pd.date_range('2020','2021', freq = 'BMS'))  
print(pd.date_range('2020','2021', freq = 'BQS-DEC'))  
print(pd.date_range('2020','2021', freq = 'BAS-DEC')) 

–> 输出的结果为:

DatetimeIndex(['2020-01-01', '2020-02-03', '2020-03-02', '2020-04-01',
               '2020-05-01', '2020-06-01', '2020-07-01', '2020-08-03',
               '2020-09-01', '2020-10-01', '2020-11-02', '2020-12-01',
               '2021-01-01'],
              dtype='datetime64[ns]', freq='BMS')
DatetimeIndex(['2020-03-02', '2020-06-01', '2020-09-01', '2020-12-01'], dtype='datetime64[ns]', freq='BQS-DEC')
DatetimeIndex(['2020-12-01'], dtype='datetime64[ns]', freq='BAS-DEC')
2.5 复合频率

复合频率就是指可以认为指定的时间范围,比如下面的几天,多个小时,多个月等

print(pd.date_range('2020/1/1','2020/2/1', freq = '7D')) 
print(pd.date_range('2020/1/1','2020/1/2', freq = '2h30min')) 
print(pd.date_range('2020','2021', freq = '2M'))  

–> 输出的结果为:

DatetimeIndex(['2020-01-01', '2020-01-08', '2020-01-15', '2020-01-22',
               '2020-01-29'],
              dtype='datetime64[ns]', freq='7D')
DatetimeIndex(['2020-01-01 00:00:00', '2020-01-01 02:30:00',
               '2020-01-01 05:00:00', '2020-01-01 07:30:00',
               '2020-01-01 10:00:00', '2020-01-01 12:30:00',
               '2020-01-01 15:00:00', '2020-01-01 17:30:00',
               '2020-01-01 20:00:00', '2020-01-01 22:30:00'],
              dtype='datetime64[ns]', freq='150T')
DatetimeIndex(['2020-01-31', '2020-03-31', '2020-05-31', '2020-07-31',
               '2020-09-30', '2020-11-30'],
              dtype='datetime64[ns]', freq='2M')
2.6 时期频率转换

有时候我们已经获取到了时间戳索引,可能需要将时期的频率进行转换,比如在进行统计的时候,有每天的销售情况,可是想按照隔天统计等,这时候就需要使用时期频率转换

1) 扩充时间数据

ts = pd.Series(np.random.rand(4),
              index = pd.date_range('20120101','20200104'))
print(ts)
print(ts.asfreq('4H',method = 'ffill'))

–> 输出的结果为:(这里是将时期扩大,会造成空白数据,method:插值模式,None不插值,ffill用之前值填充,bfill用之后值填充)

2020-01-01    0.118311
2020-01-02    0.526770
2020-01-03    0.401482
2020-01-04    0.335589
Freq: D, dtype: float64

2020-01-01 00:00:00    0.118311
2020-01-01 04:00:00    0.118311
2020-01-01 08:00:00    0.118311
2020-01-01 12:00:00    0.118311
2020-01-01 16:00:00    0.118311
2020-01-01 20:00:00    0.118311
2020-01-02 00:00:00    0.526770
2020-01-02 04:00:00    0.526770
2020-01-02 08:00:00    0.526770
2020-01-02 12:00:00    0.526770
2020-01-02 16:00:00    0.526770
2020-01-02 20:00:00    0.526770
2020-01-03 00:00:00    0.401482
2020-01-03 04:00:00    0.401482
2020-01-03 08:00:00    0.401482
2020-01-03 12:00:00    0.401482
2020-01-03 16:00:00    0.401482
2020-01-03 20:00:00    0.401482
2020-01-04 00:00:00    0.335589
Freq: 4H, dtype: float64

2) 缩短时间数据

ts = pd.Series(np.random.rand(12),
              index = pd.date_range('2020','2021',freq ='M'))
print(ts)
print(ts.asfreq('2M'))

–> 输出的结果为:(这里是默认以最后一天作为数据显示的,可以根据前面的介绍进行修改,比如每月的第一天)

2020-01-31    0.775808
2020-02-29    0.484471
2020-03-31    0.152249
2020-04-30    0.224051
2020-05-31    0.264184
2020-06-30    0.352392
2020-07-31    0.109094
2020-08-31    0.970885
2020-09-30    0.750013
2020-10-31    0.081066
2020-11-30    0.432594
2020-12-31    0.502523
Freq: M, dtype: float64

2020-01-31    0.775808
2020-03-31    0.152249
2020-05-31    0.264184
2020-07-31    0.109094
2020-09-30    0.750013
2020-11-30    0.432594
Freq: 2M, dtype: float64
2.7 超前/滞后数据

在变化百分比的时候,要求使用后面的数据与前面的数据进行运算,然后得到想要的结果,这时候就需要进行.shift()超前/滞后数据了

1) 上下移动数据

ts = pd.Series(np.random.rand(4),
              index = pd.date_range('20200101','20200104'))
print(ts,'\n')

print(ts.shift(2),'\n')
print(ts.shift(-2))

–> 输出的结果为:(数值发生变化,标签索引不变)

2020-01-01    0.054361
2020-01-02    0.365011
2020-01-03    0.974335
2020-01-04    0.907911
Freq: D, dtype: float64

2020-01-01         NaN
2020-01-02         NaN
2020-01-03    0.054361
2020-01-04    0.365011
Freq: D, dtype: float64

2020-01-01    0.974335
2020-01-02    0.907911
2020-01-03         NaN
2020-01-04         NaN
Freq: D, dtype: float64

2)计算变化百分比:该时间戳与上一个时间戳相比

per = ts/ts.shift(1) - 1
print(per)

–> 输出的结果为:(肯定是有一个数据是空值的)

2020-01-01          NaN
2020-01-02    -0.948619
2020-01-03    18.664643
2020-01-04    -0.745056
Freq: D, dtype: float64

3) 移动时间戳索引

加上freq参数:对时间戳进行位移,而不是对数值进行位移(和上面的第一个内容区别开)

print(ts.shift(2, freq = 'D'),'\n')
print(ts.shift(2, freq = 'T'))

–> 输出的结果为:(数值不变,标签索引发生变化)

2020-01-03    0.631305
2020-01-04    0.839584
2020-01-05    0.993936
2020-01-06    0.537960
Freq: D, dtype: float64

2020-01-01 00:02:00    0.631305
2020-01-02 00:02:00    0.839584
2020-01-03 00:02:00    0.993936
2020-01-04 00:02:00    0.537960
Freq: D, dtype: float64
  • 12
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lys_828

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值