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')

​normalize​​​和​​name​​参数的使用

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讲解

全部内容通过思维导图归纳如下:

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

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:

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:

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:

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:

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: