目录
time模块和datetime模块的关系
time模块
datetime模块
日期和时间数据类型
数据类型
datetime参数
字符串转换
格式说明
dateutil
NaT
时间序列基础
日期的范围、频率以及移动
频率和日期偏移量
时间序列基础频率
时区处理
时期
时期的频率转换
Timestamp与Period互转
重采样以及频率转换
resample方法的参数
OHLC重采样
groupby重采样
升采样和插值
移动窗口函数
参考
time模块偏向于底层,datetime可以看做time模块的高层应用封装。
time模块主要包括了一些比较基础的功能如 获取时间戳 time.time(),转换时间戳至时间字符串 time.ctime(a), 时间结构(由9个值构成的时间结构)time.time_struct等等。因为在数据分析中 time 模块用的不多,在此不做赘述。
datetime模块内部比较重要的两个数据类型是 datetime.datetime 和 datetime.timedelta。另外datetime.date和datetime.time可以看做是datetime.datetime的拆分(日期和时间),用法和datetime.datetime类似,所以不做详细介绍。
类型 | 格式 |
---|---|
time | 时间格式。时,分,秒, |
date | 日期格式,公历(年,月,日) |
datetime | 日期时间格式。 |
timestamp | 时间戳格式 |
timedelta | 时间差(日,秒,微秒) |
from datetime import datetime
from datetime import timedelta
now=datetime.now()
now,now.year,now.month,now.day
# (datetime.datetime(2020, 5, 30, 12, 53, 3, 452602), 2020, 5, 30)
delta= now- datetime(2020,1,1)
delta
#datetime.timedelta(days=150, seconds=46383, microseconds=452602)
v="2020-05-30"
datetime.strptime(v,'%Y-%m-%d')
datetime.datetime(2020, 5, 30, 0, 0)
格式符 | 说明 |
---|---|
%a | 星期的英文单词的缩写:如星期一, 则返回 Mon |
%A | 星期的英文单词的全拼:如星期一,返回 Monday |
%b | 月份的英文单词的缩写:如一月, 则返回 Jan |
%B | 月份的引文单词的缩写:如一月, 则返回 January |
%c | 返回datetime 的字符串表示,如03/08/15 23:01:26 |
%d | 返回的是当前时间是当前月的第几天 |
%f | 微秒的表示: 范围: [0,999999] |
%H | 以24小时制表示当前小时 |
%I | 以12小时制表示当前小时 |
%j | 返回 当天是当年的第几天 范围[001,366] |
%m | 返回月份 范围[0,12] |
%M | 返回分钟数 范围 [0,59] |
%P | 返回是上午还是下午–AM or PM |
%S | 返回秒数 范围 [0,61]。。。手册说明的 |
%U | 返回当周是当年的第几周 以周日为第一天 |
%W | 返回当周是当年的第几周 以周一为第一天 |
%w | 当天在当周的天数,范围为[0, 6],6表示星期天 |
%x | 日期的字符串表示 :03/08/15 |
%X | 时间的字符串表示 :23:22:08 |
%y | 两个数字表示的年份 15 |
%Y | 四个数字表示的年份 2015 |
%z | 与utc时间的间隔 (如果是本地时间,返回空字符串) |
%Z | 时区名称(如果是本地时间,返回空字符串) |
可以识别常用的格式。但是可能会把一些不是日期的识别为日期,比如42。
from dateutil.parser import parse
parse('2020-05-30')
# datetime.datetime(2020, 5, 30, 0, 0)
not a time
时间序列中,index类型为DateTimeIndex,序列为TimeSeries。
from datetime import datetime
from datetime import timedelta
import pandas as pd
import numpy as np
[21]
dates=[datetime(2020,5,1),datetime(2020,5,2),datetime(2020,5,3),datetime(2020,5,4),datetime(2020,5,5),datetime(2020,5,6)]
ts = pd.Series(np.random.randn(6),index=dates)
ts
2020-05-01 0.368072
2020-05-02 -0.565948
2020-05-03 -0.538496
2020-05-04 1.286633
2020-05-05 0.872500
2020-05-06 1.002520
dtype: float64
[22]
type(ts)
pandas.core.series.Series
[23]
ts+ts[::2]
2020-05-01 0.736144
2020-05-02 NaN
2020-05-03 -1.076992
2020-05-04 NaN
2020-05-05 1.745000
2020-05-06 NaN
dtype: float64
pandas有一整套标准时间序列频率以及用于重采样,频率推断、生成固定频率日期的工具。
[29]
index=pd.date_range('2020-05-01','2020-05-31')
index
DatetimeIndex(['2020-05-01', '2020-05-02', '2020-05-03', '2020-05-04',
'2020-05-05', '2020-05-06', '2020-05-07', '2020-05-08',
'2020-05-09', '2020-05-10', '2020-05-11', '2020-05-12',
'2020-05-13', '2020-05-14', '2020-05-15', '2020-05-16',
'2020-05-17', '2020-05-18', '2020-05-19', '2020-05-20',
'2020-05-21', '2020-05-22', '2020-05-23', '2020-05-24',
'2020-05-25', '2020-05-26', '2020-05-27', '2020-05-28',
'2020-05-29', '2020-05-30', '2020-05-31'],
dtype='datetime64[ns]', freq='D')
[30]
pd.date_range(end='2020-05-26',periods=20)
DatetimeIndex(['2020-05-07', '2020-05-08', '2020-05-09', '2020-05-10',
'2020-05-11', '2020-05-12', '2020-05-13', '2020-05-14',
'2020-05-15', '2020-05-16', '2020-05-17', '2020-05-18',
'2020-05-19', '2020-05-20', '2020-05-21', '2020-05-22',
'2020-05-23', '2020-05-24', '2020-05-25', '2020-05-26'],
dtype='datetime64[ns]', freq='D')
[31]
pd.date_range('2020-05-01 13:13:13',periods=20)
DatetimeIndex(['2020-05-01 13:13:13', '2020-05-02 13:13:13',
'2020-05-03 13:13:13', '2020-05-04 13:13:13',
'2020-05-05 13:13:13', '2020-05-06 13:13:13',
'2020-05-07 13:13:13', '2020-05-08 13:13:13',
'2020-05-09 13:13:13', '2020-05-10 13:13:13',
'2020-05-11 13:13:13', '2020-05-12 13:13:13',
'2020-05-13 13:13:13', '2020-05-14 13:13:13',
'2020-05-15 13:13:13', '2020-05-16 13:13:13',
'2020-05-17 13:13:13', '2020-05-18 13:13:13',
'2020-05-19 13:13:13', '2020-05-20 13:13:13'],
dtype='datetime64[ns]', freq='D')
[32]
pd.date_range('2020-05-01 13:13:13',periods=20,normalize=True)
DatetimeIndex(['2020-05-01', '2020-05-02', '2020-05-03', '2020-05-04',
'2020-05-05', '2020-05-06', '2020-05-07', '2020-05-08',
'2020-05-09', '2020-05-10', '2020-05-11', '2020-05-12',
'2020-05-13', '2020-05-14', '2020-05-15', '2020-05-16',
'2020-05-17', '2020-05-18', '2020-05-19', '2020-05-20'],
dtype='datetime64[ns]', freq='D')
pandas中的频率是由一个基础频率(base frequency)和一个乘数组成。基础频率通常是由一个字符串别名表示,M,H等,对于每个基础频率都有一个日期偏移量(date offset)与之对应。date_range方法的freq设置为'4h','4H','4D'等。数字放在别名前面。
大部分偏移量之间是可以进行相加的,也可以有对应的频率字符串。
from pandas.tseries.offsets import Hour,Minute,Day,MonthBegin
Hour(),Hour(4),Day(3),MonthBegin(2)
(, <4 * Hours>, <3 * Days>, <2 * MonthBegins>)
[39]
pd.date_range('2020-05-01','2020-07-03',freq=MonthBegin(2))
DatetimeIndex(['2020-05-01', '2020-07-01'], dtype='datetime64[ns]', freq='2MS')
[35]
pd.date_range('2020-05-01','2020-05-03',freq='8h')
DatetimeIndex(['2020-05-01 00:00:00', '2020-05-01 08:00:00',
'2020-05-01 16:00:00', '2020-05-02 00:00:00',
'2020-05-02 08:00:00', '2020-05-02 16:00:00',
'2020-05-03 00:00:00'],
dtype='datetime64[ns]', freq='8H')
[41]
pd.date_range('2020-05-01','2020-05-03',freq=Hour(4) + Minute(30))
DatetimeIndex(['2020-05-01 00:00:00', '2020-05-01 04:30:00',
'2020-05-01 09:00:00', '2020-05-01 13:30:00',
'2020-05-01 18:00:00', '2020-05-01 22:30:00',
'2020-05-02 03:00:00', '2020-05-02 07:30:00',
'2020-05-02 12:00:00', '2020-05-02 16:30:00',
'2020-05-02 21:00:00'],
dtype='datetime64[ns]', freq='270T')
[42]
pd.date_range('2020-05-01','2020-05-03',freq='4h30min')
DatetimeIndex(['2020-05-01 00:00:00', '2020-05-01 04:30:00',
'2020-05-01 09:00:00', '2020-05-01 13:30:00',
'2020-05-01 18:00:00', '2020-05-01 22:30:00',
'2020-05-02 03:00:00', '2020-05-02 07:30:00',
'2020-05-02 12:00:00', '2020-05-02 16:30:00',
'2020-05-02 21:00:00'],
dtype='datetime64[ns]', freq='270T')
别名 | 偏移量类型 | 说明 |
D | Day | 每日历日 |
B | BusinessDay | 每工作日 |
H | Hour | 每小时 |
T/min | Minute | 每分 |
S | Second | 每秒 |
L/ms | Million | 每毫秒 |
U | Micro | 每微妙 |
M | MonthEnd | 每月最后一个日历日 |
BM | BusinessMonthEnd | 每月最后一个工作日 |
MS | MonthBegin | 每月第一个日历日 |
BMS | BusinessMonthBegin | 每月第一个工作日 |
W-MON、W-TUE… | Week | 从指定的星期几开始算起,每周 |
WOM-1MON、WOM-2MON… | WeekOfMonth | 产生每月第一、二、三、四周的星期几,例如WOM-1MON表示每月的第一个星期一 |
Q-JAN、Q-FEB… | QuarterEnd | 对于以指定月份(JAN、FEB、…、DEC)结束的年度,每季度的最后一月的最后一个日历日 |
BQ-JAN、BQ-FEB… | BusinessQuarterEnd | 对于以指定月份(JAN、FEB、…、DEC)结束的年度,每季度的最后一月的最后一个工作日 |
QS-JAN、QS-FEB… | QuarterBegin | 对于以指定月份(JAN、FEB、…、DEC)结束的年度,每季度的最后一月的第一个日历日 |
BQS-JAN、BQS-FEB… | BusinessQuarterBegin | 对于以指定月份(JAN、FEB、…、DEC)结束的年度,每季度的最后一月的第一个工作日 |
A-JAN、A-FEB… | YearEnd | 每年指定月份最后一个日历日 |
BA-JAN、BA-FEB… | BusinessYearEnd | 每年指定月份最后一个工作日 |
AS-JAN、AS-FEB… | YearBegin | 每月指定月份第一个日历日 |
BAS-JAN、BAS-FEB… | BusinessYearBegin | 每月指定月份第一个工作日 |
默认情况下,pandas时间序列是native时区,tz属性是None。
不同时区是可以进行运算的,结果是UTC时间。由于时间戳是以UTC存储,因此不会发生任何转换。
时期(Period)表示时区区间。比如数日,数年,数月等。
[43]
p=pd.Period(2010,freq='A-DEC')
p
Period('2010', 'A-DEC')
[44]
p +7,p-5
(Period('2017', 'A-DEC'), Period('2005', 'A-DEC'))
[45]
pd.period_range('2010-01-01','2020-01-01',freq='8M')
PeriodIndex(['2010-01', '2010-09', '2011-05', '2012-01', '2012-09', '2013-05',
'2014-01', '2014-09', '2015-05', '2016-01', '2016-09', '2017-05',
'2018-01', '2018-09', '2019-05', '2020-01'],
dtype='period[8M]', freq='8M')
Period对象可以通过asfreq方法转换成别的频率。
p=pd.Period(2010,freq='A-DEC')
p2=p.asfreq('M',how="start")
p,p2,p.asfreq('D',how="start")
(Period('2010', 'A-DEC'), Period('2010-01', 'M'), Period('2010-01-01', 'D'))
p=pd.Period(2010,freq='A-DEC')
ts=p.to_timestamp('S')
p2=ts.to_period('D')
p,ts,p2
(Period('2010', 'A-DEC'),
Timestamp('2010-01-01 00:00:00'),
Period('2010-01-01', 'D'))
重采样指将时间序列从一个频率转换到另一个频率的处理过程。将高频率聚合到低频率称为降采样(downsampling),低频率转换到高频率称为升采样(upsmapling)。并不是所有的重采样都这样,比如星期一转换为星期三
参数 | 说明 |
---|---|
freq | 表示重采样频率,例如‘M’、‘5min’,Second(15) |
how=’mean’ | 用于产生聚合值的函数名或数组函数,例如‘mean’、‘ohlc’、np.max等,默认是‘mean’,其他常用的值由:‘first’、‘last’、‘median’、‘max’、‘min’。此参数已经过时了。how全部变成了方法了。例如ts.resample('M').max() |
axis=0 | 默认是纵轴,横轴设置axis=1 |
fill_method = None | 升采样时如何插值,比如‘ffill’、‘bfill’等 |
closed = ‘right’ | 在降采样时,各时间段的哪一段是闭合的,‘right’或‘left’,默认‘right’ |
label= ‘right’ | 在降采样时,如何设置聚合值的标签,例如,9:30-9:35会被标记成9:30还是9:35,默认9:35 |
loffset = None | 面元标签的时间校正值,比如‘-1s’或Second(-1)用于将聚合标签调早1秒 |
limit=None | 在向前或向后填充时,允许填充的最大时期数 |
kind = None | 聚合到时期(‘period’)或时间戳(‘timestamp’),默认聚合到时间序列的索引类型 |
convention = None | 当重采样时期时,将低频率转换到高频率所采用的约定(start或end)。默认‘end’ |
rng=pd.date_range('2020-05-01',periods=10,freq='D')
ts=pd.Series(np.random.randn(len(rng)),index=rng)
ts
2020-05-01 0.188817
2020-05-02 -0.900274
2020-05-03 -1.786289
2020-05-04 -0.567210
2020-05-05 1.122737
2020-05-06 0.781383
2020-05-07 1.865210
2020-05-08 -1.128856
2020-05-09 -0.069579
2020-05-10 0.320410
Freq: D, dtype: float64
[90]
ts.resample('3D').max()
2020-05-01 0.188817
2020-05-04 1.122737
2020-05-07 1.865210
2020-05-10 0.320410
Freq: 3D, dtype: float64
金融领域各面源值:open(开盘),close(收盘),high(最高),low(最低)
ts.resample('2d').ohlc()
open high low close
2020-05-01 0.188817 0.188817 -0.900274 -0.900274
2020-05-03 -1.786289 -0.567210 -1.786289 -0.567210
2020-05-05 1.122737 1.122737 0.781383 0.781383
2020-05-07 1.865210 1.865210 -1.128856 -1.128856
2020-05-09 -0.069579 0.320410 -0.069579 0.320410
ts.groupby(lambda x:x.month).sum()
5 -0.17365
dtype: float64
使用pad方法填充nan值。
使用bfill方法填充nan值。
通过apply运行一个自定义函数
DataFrame.rolling(window, min_periods=None, center=False, win_type=None, on=None, axis=0, closed=None)
参数:
各对象的说明:https://docs.python.org/zh-cn/3/library/datetime.html#datetime-objects
移动窗口函数:https://www.cnblogs.com/nxf-rabbit75/archive/2019/04/08/10669516.html