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讲解
全部内容通过思维导图归纳如下:
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