时间序列夹杂其他格式errors参数:
# 当一组时间序列中夹杂其他格式数据,可用errors参数返回 # errors = 'ignore':不可解析时返回原始输入,这里就是直接生成一般数组 date1 = ['2020-2-1','2020-2-2','2020-2-3','hello world!','2020-2-5','2020-2-6'] t1 = pd.to_datetime(date1, errors = 'ignore') print(t1,type(t1)) print("*"*10) # errors = 'coerce':不可扩展,缺失值返回NaT(Not a Time),结果认为DatetimeIndex t2 = pd.to_datetime(date1, errors = 'coerce') print(t2,type(t2))
输出为:
2. date_range方法
date_range是一种生成连续间隔时间的一种方法,其重要的参数为start, end, freq, periods,它们分别表示开始时间,结束时间,时间间隔,时间戳个数。其中,四个中的三个参数决定了,那么剩下的一个就随之确定了。这里要注意,开始或结束日期如果作为端点则它会被包含:
# pd.date_range()-日期范围:生成日期范围 # 2种生成方式:①start + end; ②start/end + periods # 默认频率:day # normalize:时间参数值正则化到午夜时间戳 rng1 = pd.date_range('1/1/2020','1/3/2020',name = 'index_name', normalize=True) rng2 = pd.date_range(start = '1/1/2020 10:10', periods = 3, normalize=True) rng3 = pd.date_range(end = '1/30/2020 15:00:00', periods = 3) # 增加了时、分、秒 print(rng1) print(rng2) print(rng3) print('-------') # 直接生成DatetimeIndex # pd.date_range(start=None, end=None, periods=None, freq='D', tz=None, normalize=False, name=None, closed=None, **kwargs) # start:开始时间 # end:结束时间 # periods:偏移量 # freq:频率,默认天,pd.date_range()默认频率为日历日,pd.bdate_range()默认频率为工作日 # tz:时区 # normalize:时间参数值正则化到午夜时间戳(这里最后就直接变成0:00:00,并不是10:10:00) # name:索引对象名称 # closed:默认为None的情况下,左闭右闭,left则左闭右开,right则左开右闭 print(pd.date_range('20200101','20200104')) # 20170101也可读取 # print(pd.date_range('20200101','20200104',closed = 'right')) # print(pd.date_range('20200101','20200104',closed = 'left')) print('-------') # closed:默认为None的情况下,左闭右闭,left则左闭右开,right则左开右闭 # pd.bdate_range()默认频率为工作日 print(pd.bdate_range('20200101','20200107')) print('-------') # pd.bdate_range()默认频率为工作日
输出为:
DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03'], dtype='datetime64[ns]', name='index_name', freq='D') DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03'], dtype='datetime64[ns]', freq='D') DatetimeIndex(['2020-01-28 15:00:00', '2020-01-29 15:00:00', '2020-01-30 15:00:00'], dtype='datetime64[ns]', freq='D') ------- DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04'], dtype='datetime64[ns]', freq='D') ------- DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-06', '2020-01-07'], dtype='datetime64[ns]', freq='B') ------- [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')]
freq参数的设置
pd.date_range()-日期范围:频率(1)
默认freq = ‘D’:每日历日
B:每工作日
H:每小时
T/MIN:每分
S:每秒
L:每毫秒(千分之一秒)
U:每微秒(百万分之一秒)
freq = ‘W-MON’ # W-MON:从指定星期几开始算起,每周
星期几缩写:MON/TUE/WED/THU/FRI/SAT/SUN
freq = ‘WOM-2MON’
WOM-2MON:每月的第几个星期几开始算,这里是每月第二个星期一
pd.date_range()-日期范围:频率(2)
M:每月最后一个日历日
Q-月:Q-DEC指定月为季度末,每个季度末最后一月的最后一个日历日
A-月:A-DEC每年指定月份的最后一个日历日
月缩写: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
BM:每月最后一个工作日
BQ-月:BQ-DEC指定月为季度末,每个季度末最后一月的最后一个工作日
BA-月:BA-DEC每年指定月份的最后一个工作日,这里是12月
M:MS每月第一个日历日
Q-月:QS-DEC指定月为季度末,每个季度末最后一月的第一个日历日
A-月:AS-DEC每年指定月份的第一个日历日
BM:BMS每月第一个工作日
BQ-月:BQS-DEC指定月为季度末,每个季度末最后一月的第一个工作日
BA-月:BAS-DEC每年指定月份的第一个工作日
pd.date_range()-日期范围:复合频率
freq = ‘7D’ # 7天
freq = ‘2h30min’ # 2小时30分钟
freq = ‘2M’ # 2月,每月最后一个日历日
# asfreq:时期频率转换 ts = pd.Series(np.random.rand(4), index = pd.date_range('20170101','20170104')) print(ts) print(ts.asfreq('12H',method = 'ffill')) # 改变频率,这里是D改为12H # method:插值模式,None不插值,ffill用之前值填充,bfill用之后值填充
输出为:
# pd.date_range()-日期范围:超前/滞后数据 ts = pd.Series(np.arange(4), index = pd.date_range('20200101','20200104')) print(ts) print(ts.shift(2)) # print(ts.shift(-2)) print('------') # 正数:数值后移(滞后);负数:数值前移(超前) per = ts/ts.shift(1) - 1 print(per) print('------') # 计算变化百分比,这里计算:该时间戳与上一个时间戳相比,变化百分比 print(ts.shift(2, freq = 'D')) # 天 # print(ts.shift(2, freq = 'T')) # 小时 # 加上freq参数:对时间戳进行位移,而不是对数值进行位移
输出为:
3. dt对象
在时序类型的序列上定义了dt对象来完成许多时间序列的相关操作。这里对于datetime64[ns]类型而言,可以大致分为三类操作:取出时间相关的属性、判断时间戳是否满足条件、取整操作。
第一类操作的常用属性包括:date, time, year, month, day, hour, minute, second, microsecond, nanosecond, dayofweek, dayofyear, weekofyear, daysinmonth, quarter,其中daysinmonth, quarter分别表示该月一共有几天和季度。
s = pd.Series(pd.date_range('2020-1-1','2020-1-3', freq='D')) s.dt.date # 日期 # s.dt.time 时间
输出为:
0 2020-01-01 1 2020-01-02 2 2020-01-03 dtype: object
此外,可以通过month_name, day_name返回英文的月名和星期名,注意它们是方法而不是属性:
print(s.dt.month_name()) print(s.dt.day_name())
输出为:
0 January 1 January 2 January dtype: object 0 Wednesday 1 Thursday 2 Friday dtype: object
第二类判断操作主要用于测试是否为月/季/年的第一天或者最后一天:
# 第二类判断操作主要用于测试是否为月/季/年的第一天或者最后一天: print(s.dt.is_year_start) # 还可选 is_quarter/month_start s.dt.is_year_end # 还可选 is_quarter/month_end
输出为:
0 True 1 False 2 False dtype: bool 0 False 1 False 2 False dtype: bool
第三类的取整操作包含round, ceil, floor,它们的公共参数为freq,常用的包括H, min, S(小时、分钟、秒)
s = pd.Series(pd.date_range('2020-1-1 20:35:00', '2020-1-1 22:35:00', freq='45min')) print(s) print(s.dt.round('1H')) print(s.dt.ceil('1H')) print(s.dt.floor('1H'))
输出为:
0 2020-01-01 20:35:00 1 2020-01-01 21:20:00 2 2020-01-01 22:05:00 dtype: datetime64[ns] 0 2020-01-01 21:00:00 1 2020-01-01 21:00:00 2 2020-01-01 22:00:00 dtype: datetime64[ns] 0 2020-01-01 21:00:00 1 2020-01-01 22:00:00 2 2020-01-01 23:00:00 dtype: datetime64[ns] 0 2020-01-01 20:00:00 1 2020-01-01 21:00:00 2 2020-01-01 22:00:00 dtype: datetime64[ns]
4. 时间戳的切片和索引
一般而言,时间戳序列作为索引使用。如果想要选出某个子时间戳序列,第一类方法是利用dt对象和布尔条件联合使用,另一种方式是利用切片,后者常用于连续时间戳。下面,举一些例子说明:
构建series:
s = pd.Series(np.random.randint(2,size=366), index=pd.date_range('2020-01-01','2020-12-31')) s.head()
输出为:
利用dt对象和布尔条件过滤
idx = pd.Series(s.index).dt print(idx) s[(idx.is_month_start|idx.is_month_end).values].head()
输出为:
取出5月到7月15日中间的数据
s['2020-05':'2020-7-15'].head() • 1
输出为: