python datetime 加一个月_python时间模块:datetime

#datetime.date(), datetime.datetime(), datetime.timedelta()

# datetime.date:date对象

today = datetime.date.today()

today,type(today)

2017-12-26

str(today),type(str(today))

[output]:

2017-12-26

datetime.date(2016,6,1)

[output]:

2016-06-01

# datetime.datetime:datetime对象

# (年,月,日,时,分,秒),至少输入年月日

now = datetime.datetime.now()

t1 = datetime.datetime(2016,6,1)

t2 = datetime.datetime(2014,1,1,12,44,33)

[output]:

016-06-01 00:00:00 2014-01-01 12:44:33

# 相减得到时间差 —— timedelta

# datetime.timedelta:时间差

t2-t1

yestoday = today - datetime.timedelta(1) #

today - datetime.timedelta(7)

# 时间差主要用作时间的加减法,相当于可被识别的时间“差值”

#日期解析方法:parser.parse

# 各种格式可以解析,但无法支持中文

from dateutil.parser import parse

print(parse('2000-1-1'),'\n',

parse('5/1/2014'),'\n',

parse('5/1/2014', dayfirst = True),'\n', # 国际通用格式中,日在月之前,可以通过dayfirst来设置

parse('22/1/2014'),'\n',

parse('Jan 31, 1997 10:45 PM'))

[output]:

2000-01-01 00:00:00

2014-05-01 00:00:00

2014-01-05 00:00:00

2014-01-22 00:00:00

1997-01-31 22:45:00

#Pandas时刻数据:Timestamp

#时刻数据代表时间点,是pandas的数据类型,是将值与时间点相关联的最基本类型的时间序列数据

#pandas.Timestamp()

# 直接生成pandas的时刻数据 → 时间戳

# 数据类型为 pandas的Timestamp

date1 = datetime.datetime(2016,12,1,12,45,30)

t1 = pd.Timestamp(date1)

t2 = pd.to_datetime(date1)

[output]:

Timestamp('2016-12-01 12:45:30')

# pd.to_datetime():

#如果是单个时间数据,转换成pandas的时刻数据,数据类型为Timestamp

# 多个时间数据,将会转换为pandas的DatetimeIndex

lst_date = [ '2017-12-21', '2017-12-22', '2017-12-23']

t3 = pd.to_datetime(lst_date)

[output]:

DatetimeIndex(['2017-12-21', '2017-12-22', '2017-12-23'], dtype='datetime64[ns]', freq=None)

# 当一组时间序列中夹杂其他格式数据,可用errors参数返回

# errors = 'ignore':不可解析时返回原始输入,这里就是直接生成一般数组

date3 = ['2017-2-1','2017-2-2','2017-2-3','hello world!','2017-2-5','2017-2-6']

t3 = pd.to_datetime(date3, errors = 'ignore')

[output]:

['2017-2-1' '2017-2-2' '2017-2-3' 'hello world!' '2017-2-5' '2017-2-6']

# errors = 'coerce':不可扩展,缺失值返回NaT(Not a Time),结果认为DatetimeIndex

t4 = pd.to_datetime(date3, errors = 'coerce')

[output]:

DatetimeIndex(['2017-02-01', '2017-02-02', '2017-02-03', 'NaT', '2017-02-05',

'2017-02-06'],

dtype='datetime64[ns]', freq=None)

#Pandas时间戳索引:DatetimeIndex

#核心:pd.date_range()

# 直接生成时间戳索引,支持str、datetime.datetime

# 单个时间戳为Timestamp,多个时间戳为DatetimeIndex

rng = pd.DatetimeIndex(['12/1/2017','12/2/2017','12/3/2017','12/4/2017','12/5/2017'])

[output]:

DatetimeIndex(['2017-12-01', '2017-12-02', '2017-12-03', '2017-12-04',

'2017-12-05'],

dtype='datetime64[ns]', freq=None)

st = pd.Series(np.random.rand(len(rng)), index = rng)

# pd.date_range()-日期范围:生成日期范围

# 2种生成方式:①start + end; ②start/end + periods

# 默认频率:day

# 直接生成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:时区

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) # 增加了时、分、秒

# normalize:时间参数值正则化到午夜时间戳(这里最后就直接变成0:00:00,并不是15:30:00)

# name:索引对象名称

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

# closed:默认为None的情况下,左闭右闭,left则左闭右开,right则左开右闭

pd.date_range('20170101','20170104')) # 20170101也可读取

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

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

# pd.bdate_range()默认频率为工作日

print(pd.bdate_range('20170101','20170107'))

# 直接转化为list,元素为Timestamp

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

# pd.date_range()-日期范围:频率(1)

pd.date_range('2017/1/1','2017/1/4') # 默认freq = 'D':每日历日

pd.date_range('2017/1/1','2017/1/4', freq = 'B') # B:每工作日

pd.date_range('2017/1/1','2017/1/2', freq = 'H') # H:每小时

pd.date_range('2017/1/1 12:00','2017/1/1 12:10', freq = 'T') # T/MIN:每分

pd.date_range('2017/1/1 12:00:00','2017/1/1 12:00:10', freq = 'S') # S:每秒

pd.date_range('2017/1/1 12:00:00','2017/1/1 12:00:10', freq = 'L') # L:每毫秒(千分之一秒)

pd.date_range('2017/1/1 12:00:00','2017/1/1 12:00:10', freq = 'U') # U:每微秒(百万分之一秒)

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

# W-MON:从指定星期几开始算起,每周

# 星期几缩写:MON/TUE/WED/THU/FRI/SAT/SUN

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

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

# pd.date_range()-日期范围:频率(2)

# 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

pd.date_range('2017','2018', freq = 'M')

pd.date_range('2017','2020', freq = 'Q-DEC')

pd.date_range('2017','2020', freq = 'A-DEC')

# BM:每月最后一个工作日

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

# BA-月:每年指定月份的最后一个工作日

pd.date_range('2017','2018', freq = 'BM')

pd.date_range('2017','2020', freq = 'BQ-DEC')

pd.date_range('2017','2020', freq = 'BA-DEC')

# M:每月第一个日历日

# Q-月:指定月为季度末,每个季度末最后一月的第一个日历日

# A-月:每年指定月份的第一个日历日

pd.date_range('2017','2018', freq = 'MS')

pd.date_range('2017','2020', freq = 'QS-DEC')

pd.date_range('2017','2020', freq = 'AS-DEC')

# BMS:每月第一个工作日

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

# BAS-月:每年指定月份的第一个工作日

pd.date_range('2017','2018', freq = 'BMS'))

pd.date_range('2017','2020', freq = 'BQS-DEC')

pd.date_range('2017','2020', freq = 'BAS-DEC')

#复合频率

# pd.date_range()-日期范围:复合频率

pd.date_range('2017/1/1','2017/2/1', freq = '7D') # 7天

pd.date_range('2017/1/1','2017/1/2', freq = '2h30min') # 2小时30分钟

pd.date_range('2017','2018', freq = '2M') # 2月,每月最后一个日历日

# asfreq:时期频率转换

ts = pd.Series(np.random.rand(4),

index = pd.date_range('20170101','20170104'))

ts.asfreq('4H',method = 'ffill')

# 改变频率,这里是D改为4H

# method:插值模式,None不插值,ffill用之前值填充,bfill用之后值填充

# pd.date_range()-日期范围:超前/滞后数据

ts = pd.Series(np.random.rand(4),

index = pd.date_range('20170101','20170104'))

[output]:

2017-01-01 0.967312

2017-01-02 0.945871

2017-01-03 0.555347

2017-01-04 0.872889

Freq: D, dtype: float64

# 正数:数值后移(滞后);负数:数值前移(超前)

ts.shift(2)

2017-01-01 NaN

2017-01-02 NaN

2017-01-03 0.967312

2017-01-04 0.945871

Freq: D, dtype: float64

ts.shift(-2)

2017-01-01 0.555347

2017-01-02 0.872889

2017-01-03 NaN

2017-01-04 NaN

Freq: D, dtype: float64

# 计算变化百分比,这里计算:该时间戳与上一个时间戳相比,变化百分比

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

# 加上freq参数:对时间戳进行位移,而不是对数值进行位移

ts.shift(2, freq = 'D')

2017-01-03 0.967312

2017-01-04 0.945871

2017-01-05 0.555347

2017-01-06 0.872889

Freq: D, dtype: float64

ts.shift(2, freq = 'T')

2017-01-01 00:02:00 0.967312

2017-01-02 00:02:00 0.945871

2017-01-03 00:02:00 0.555347

2017-01-04 00:02:00 0.872889

Freq: D, dtype: float64

#Pandas时期:Period

#核心:pd.Period()

# pd.Period()创建时期

# pd.Period()参数:一个时间戳 + freq 参数 → freq 用于指明该 period 的长度,时间戳则说明该 period 在时间轴上的位置

p = pd.Period('2017', freq = 'M') # 生成一个以2017-01开始,月为频率的时间构造器

# 通过加减整数,将周期整体移动

# 这里是按照 月、年 移动

p + 1

p - 2

pd.Period('2012', freq = 'A-DEC') - 1

[output]:

2017-01

2017-02

2016-11

2011

# pd.period_range()创建时期范围

# 数据格式为PeriodIndex,单个数值为Period

prng = pd.period_range('1/1/2011', '1/1/2012', freq='M')

ts = pd.Series(np.random.rand(len(prng)), index = prng)

# asfreq:频率转换

p = pd.Period('2017','A-DEC')

p.asfreq('M', how = 'start') # 也可写 how = 's'

p.asfreq('D', how = 'end') # 也可写 how = 'e'

# 通过.asfreq(freq, method=None, how=None)方法转换成别的频率

[output]:

2017

2017-01

2017-12-31

prng = pd.period_range('2017','2018',freq = 'M')

ts1 = pd.Series(np.random.rand(len(prng)), index = prng)

ts2 = pd.Series(np.random.rand(len(prng)), index = prng.asfreq('D', how = 'start'))

# asfreq也可以转换TIMESeries的index

[output]:

2017-01 0.060797

2017-02 0.441994

2017-03 0.971933

2017-04 0.000334

2017-05 0.545191

Freq: M, dtype: float64 13

2017-01-01 0.447614

2017-02-01 0.679438

2017-03-01 0.891729

2017-04-01 0.949993

2017-05-01 0.942548

Freq: D, dtype: float64 13

# 时间戳与时期之间的转换:pd.to_period()、pd.to_timestamp()

rng = pd.date_range('2017/1/1', periods = 10, freq = 'M')

prng = pd.period_range('2017','2018', freq = 'M')

# 每月最后一日,转化为每月

ts1 = pd.Series(np.random.rand(len(rng)), index = rng)

print(ts1.head())

print(ts1.to_period().head())

[output]:

2017-01-31 0.125288

2017-02-28 0.497174

2017-03-31 0.573114

2017-04-30 0.665665

2017-05-31 0.263561

Freq: M, dtype: float64

2017-01 0.125288

2017-02 0.497174

2017-03 0.573114

2017-04 0.665665

2017-05 0.263561

Freq: M, dtype: float64

# 每月,转化为每月第一天

ts2 = pd.Series(np.random.rand(len(prng)), index = prng)

print(ts2.head())

print(ts2.to_timestamp().head())

[output]:

2017-01 0.748661

2017-02 0.095891

2017-03 0.280341

2017-04 0.569813

2017-05 0.067677

Freq: M, dtype: float64

2017-01-01 0.748661

2017-02-01 0.095891

2017-03-01 0.280341

2017-04-01 0.569813

2017-05-01 0.067677

Freq: MS, dtype: float64

#时间序列 - 索引及切片

#TimeSeries是Series的一个子类,所以Series索引及数据选取方面的方法基本一样

#同时TimeSeries通过时间序列有更便捷的方法做索引和切片

rng = pd.date_range('2017/1','2017/3')

ts = pd.Series(np.random.rand(len(rng)), index = rng)

# 基本下标位置索引

ts[0]

ts[:2]

[output]:

2017-01-01 0.107736

2017-01-02 0.887981

2017-01-03 0.712862

2017-01-04 0.920021

2017-01-05 0.317863

Freq: D, dtype: float64

0.107735945027

2017-01-01 0.107736

2017-01-02 0.887981

Freq: D, dtype: float64

# 时间序列标签索引,支持各种时间字符串,以及datetime.datetime

ts['2017/1/2']

ts['20170103']

ts['1/10/2017']

ts[datetime(2017,1,20)]

# 时间序列由于按照时间先后排序,故不用考虑顺序问题

# 索引方法同样适用于Dataframe

# 切片

rng = pd.date_range('2017/1','2017/3',freq = '12H')

ts = pd.Series(np.random.rand(len(rng)), index = rng)

# 和Series按照index索引原理一样,也是末端包含

ts['2017/1/5':'2017/1/10']

# 传入月,直接得到一个切片

ts['2017/2'].head()

# 重复索引的时间序列

dates = pd.DatetimeIndex(['1/1/2015','1/2/2015','1/3/2015','1/4/2015','1/1/2015','1/2/2015'])

ts = pd.Series(np.random.rand(6), index = dates)

[output]:

2015-01-01 0.300286

2015-01-02 0.603865

2015-01-03 0.017949

2015-01-04 0.026621

2015-01-01 0.791441

2015-01-02 0.526622

dtype: float64

# index有重复,is_unique检查 → values唯一,index不唯一

ts.is_unique,ts.index.is_unique

True False

# index有重复的将返回多个值

ts['20150101'],type(ts['20150101'])

2015-01-01 0.300286

2015-01-01 0.791441

dtype: float64

ts['20150104'],type(ts['20150104'])

2015-01-04 0.026621

dtype: float64

print(ts.groupby(level = 0).mean())

# 通过groupby做分组,重复的值这里用平均值处理

2015-01-01 0.545863

2015-01-02 0.565244

2015-01-03 0.017949

2015-01-04 0.026621

dtype: float64

#时间序列 - 重采样

#将时间序列从一个频率转换为另一个频率的过程,且会有数据的结合

#降采样:高频数据 → 低频数据,eg.以天为频率的数据转为以月为频率的数据

#升采样:低频数据 → 高频数据,eg.以年为频率的数据转为以月为频率的数据

# 重采样:.resample()

# 创建一个以天为频率的TimeSeries,重采样为按5天为频率

rng = pd.date_range('20170101', periods = 12)

ts = pd.Series(np.arange(12), index = rng)

[output]:

2017-01-01 0

2017-01-02 1

2017-01-03 2

2017-01-04 3

2017-01-05 4

2017-01-06 5

2017-01-07 6

2017-01-08 7

2017-01-09 8

2017-01-10 9

2017-01-11 10

2017-01-12 11

Freq: D, dtype: int32

# ts.resample('5D'):得到一个重采样构建器,频率改为5天

# ts.resample('5D').sum():得到一个新的聚合后的Series,聚合方式为求和

# freq:重采样频率 → ts.resample('5D')

# .sum():聚合方法

ts_re = ts.resample('5D')

[output]:

DatetimeIndexResampler [freq=<5 * Days>, axis=0, closed=left, label=left, convention=start, base=0]

ts_re2 = ts.resample('5D').sum()

[output]:

2017-01-01 10

2017-01-06 35

2017-01-11 21

Freq: 5D, dtype: int32

ts.resample('5D').mean(),'→ 求平均值\n'

ts.resample('5D').max(),'→ 求最大值\n'

ts.resample('5D').min(),'→ 求最小值\n'

ts.resample('5D').median(),'→ 求中值\n'

ts.resample('5D').first(),'→ 返回第一个值\n'

ts.resample('5D').last(),'→ 返回最后一个值\n'

ts.resample('5D').ohlc(),'→ OHLC重采样\n'

# OHLC:金融领域的时间序列聚合方式 → open开盘、high最大值、low最小值、close收盘

# 降采样

# closed:各时间段哪一端是闭合(即包含)的,默认 左闭右闭

# 详解:这里values为0-11,按照5D重采样 → [1,2,3,4,5],[6,7,8,9,10],[11,12]

# left指定间隔左边为结束 → [1,2,3,4,5],[6,7,8,9,10],[11,12]

# right指定间隔右边为结束 → [1],[2,3,4,5,6],[7,8,9,10,11],[12]

ts.resample('5D').sum(),'→ 默认

ts.resample('5D', closed = 'left').sum(),'→ left

ts.resample('5D', closed = 'right').sum(),'→ right

# label:聚合值的index,默认为取左

# 值采样认为默认(这里closed默认)

ts.resample('5D', label = 'left').sum(),'→ leftlabel

ts.resample('5D', label = 'right').sum(),'→ rightlabel

# 升采样及插值

rng = pd.date_range('2017/1/1 0:0:0', periods = 5, freq = 'H')

ts = pd.DataFrame(np.arange(15).reshape(5,3),

index = rng,

columns = ['a','b','c'])

# 低频转高频,主要是如何插值

# .asfreq():不做填充,返回Nan

# .ffill():向上填充

# .bfill():向下填充

ts.resample('15T').asfreq()

ts.resample('15T').ffill()

ts.resample('15T').bfill()

# 时期重采样 - Period

prng = pd.period_range('2016','2017',freq = 'M')

ts = pd.Series(np.arange(len(prng)), index = prng)

ts.resample('3M').sum() # 降采样

ts.resample('15D').ffill() # 升采样

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值