目录
一:时间处理
1.常用频率和日期偏移量:编辑
2.pandas.Series.dt对象能够返回的信息有:
二.格式化日期
1.pandas中有四种时间类型:
2.时间序列TimeSries
3.时间索引的特性
4.时间格式转换:
1.strptime与strftime
2.pd.Timestamp:
3.pandas.date_range()
三:Pandas中的时期的频率转换
1.Shift时间频率进行位移
2.period()
3.resample()
4.时间戳和时期之间的转换
pd.to_datetime实现日期字符串转日期
pd.date_range生成日期序列
pd.date_range(start=None, end=None, periods=None, freq=‘D’)
start:起始日期,字符串
end:终止日期,字符串
periods:期数,取值为整数或None
freq:频率或日期偏移量,取值为string或DateOffset,默认为’D’
eg:
pd.date_range(start='20170101',end='20170110')
pd.date_range(start='20170101',periods=10)
pandas 的 pandas.Series.dt 可以获得日期/时间类型的相关信息,返回值均为int型。比如:
data['入住日期'].dt.year #获取年份
data['入住日期'].dt.month #获取月份
data['入住日期'].dt.quarter #获取季度#为数据表添加新列’入住月份’:
#提取data['入住日期']的月份信息并存到新的一列中
data.loc[:,'入住月份']=data['入住日期'].dt.month
data.head()
为数据表添加新列’in_weekday’:
#提取data['入住日期']的weekday信息并存到新的一列中
data.loc[:,'in_weekday']=data['入住日期'].dt.weekday
data.head()
1.strftime函数实际上是datetime模块中的函数,并不是pandas中的成员,在实际工作中我们常用这种方式对日期进行格式化
api:datetime.strftime(date,format_str)
date:需要格式化的日期
format_str:格式化字符串#首先需要引入datetime模块
from datetime import datetime
#配合apply函数
data.loc[:,'入住年月']=data['入住日期'].apply(lambda x:datetime.strftime(x,"%Y-%m"))
data.head()2.Series.dt.to_period 另一种方法。第二种方法使用起来更加简单,参数 M 表示月份,Q 表示季度,A 表示年度,D 表示按天,这几个参数比较常用。
data.loc[:,'入住年月2']= data['入住日期'].dt.to_period('M')
data.head()
Date times : 日期和时间,可以带时区。和标准库中的 datetime.datetime 类似。
Time deltas: 绝对持续时间,和 标准库中的 datetime.timedelta 类似。
Time spans: 由时间点及其关联的频率定义的时间跨度。
Date offsets:基于日历计算的时间 和 dateutil.relativedelta.relativedelta 类似。
# 生成时间数据,freq参数指定时间单位:S-秒,M-分,D-天,M-月
rng = pd.date_range('1/1/2012', periods=100, freq='S')
ts = pd.Series(np.random.randint(0, 500, len(rng)), index=rng)
ts.resample('5Min').sum()
# 时区表示
ts_utc = ts.tz_localize('UTC')
ts_utc = ts.tz_localize('US/Eastern')
# 时间格式截断,将日期时间离散化,转换为更粗的粒度,转换为日、月、季度、年
ps = ts.to_period('Y') # 截断为年份,A也可以
ps = ts.to_period('M') # 截断为月份
ps = ts.to_period('D') # 截断为日期
ps = ts.to_period('Q') # 截断为季度
# 指定时间显示格式,将日期时间离散化,转换为更粗的粒度,转换为日、周、月、季度、年
ps = ts.to_period('D').strftime('%Y, %m, %d, %B, %r')
# 周的索引
ts.to_period('D').loc[pd.to_datetime('2022-01-31/2022-02-06')]
# 将日期时间离散化,转换为更细的粒度,例如:日转换为时、分、秒等,假设有时间索引的df
df.asfreq(freq='D',fill_value=0)
df.asfreq(freq='D',method='ffill')
# 时间段转换为时间
ts = ps.to_timestamp()
# 字符串转换为时间,以日期的字符串timestamp为例
df['timestamp'].astype('datetime64') # 仅限时间格式为yyyy-mm-dd
df['timestamp'].astype('datetime64[ns]') # 'datetime64'等同于'datetime64[ns]'
df['timestamp'] = pd.to_datetime(df['timestamp']) # 时间格式为yyyy-mm-dd
df['timestamp'] = pd.to_datetime(df['timestamp'], format='%Y%m%d') # 这里将yyyymmdd格式时间解析为时间类型字段,其他时间格式必需指定format,否则会解析为1970-01-01,
import numpy as np
dates=['20220101','20220102','20220103','20220104','20220105']
df = pd.DataFrame(np.random.randn(5), index=[pd.to_datetime(date) for date in dates])
# 时间索引的切片,类似下标索引,等同于使用iloc
df[::2] # 正向步长为2
df[::-2] # 逆向步长为2
df + df[::2] # 对应索引做加法运算
# 时间索引的访问,无法使用键值索引,必需使用loc
df.loc['20220101'] # 日期格式1
df.loc['2022-01-01'] # 日期格式2
df.loc['20220101': '20220103'] # 日期格式1,左闭右闭
df.loc['2022-01-01': '2022-01-03'] #日期格式2,左闭右闭
df.loc['2022'] # 部分日期,按年筛选
df.loc['2022-01'] # 部分日期,按年月筛选,必需加横线
# 时间索引的洞察,查看年月日
df.index.year # 查看时间索引的年份
df.index.month # 查看时间索引的月份
df.index.day # 查看时间索引的日期
df.index.weekofyear # 查看时间索引都是本年的第几周
df.index.weekday # 查看时间索引的星期
# 时间索引的偏移
df['A'].shift(2) # 数据向下偏移2行,头两行值为NaN
df.tshift(2, freq='D') # 时间索引加2天
df.tshift(2, freq='M') # 时间索引加2月,全部时间索引变为隔月月末一天
df.tshift(2, freq='Y') # 时间索引加2年,全部时间索引变为隔年月末一天
# 注意:如果时间列存在重复值,则tshift报错cannot reindex from a duplicate axis,此时必须通过datetime.timedelta完成
import datetime
df.assign(date=lambda x: x['date'].astype('datetime64[ns]').apply(lambda x: x + datetime.timedelta(1)))
# 时间索引的填充
df.asfreq(freq='30S', fill_value=1.0) # 增加时间切片,每个索引之间按照30S生成新的切片,默认值为1.0
df.asfreq(freq='30S', method='bfill') # 增加时间切片,每个索引之间按照30S生成新的切片,默认值向下填充(以下一个非空值为准)
时间格式转换
代码 说明
%Y 4位数的年
%y 2位数的年
%m 2位数的月[01,12]
%d 2位数的日[01,31]
%H 时(24小时制)[00,23]
%l 时(12小时制)[01,12]
%M 2位数的分[00,59]
%S 秒[00,61]有闰秒的存在
%w 用整数表示的星期几[0(星期天),6]
%F %Y-%m-%d简写形式例如,2017-06-27
%D %m/%d/%y简写形式
# 日期转换为字符串,strftime(string from time)
stamp = datetime(2022, 2, 5)
stamp.strftime('%Y-%m-%d') # '2022-02-05'
# 字符串转换为日期,strptime(string parse to time)
strdate = '2022-02-05'
stamp = datetime.datetime.strptime(strdate, '%Y-%m-%d') # datetime.datetime(2022, 2, 5, 0, 0)
pd.Timestamp(ts_input, freq=None, tz=None, unit=None,
year=None, month=None, day=None, hour=None, minute=None,
second=None, microsecond=None, nanosecond=None, tzinfo=None)
ts_input:datetime-like,str,int,float#要转换为时间戳的值
freq: str,DateOffset
tz: str,pytz.timezone,dateutil.tz.tzfile或None#时间时区
unit : str#如ts_input为int或float,则用于转换的单位。该有效值为'D','h','m','s','ms','us'和'ns'
year, month, day : int
hour, minute, second, microsecond : int, optional, default 0
nanosecond: int,optional,默认值为0
tzinfo: datetime.tzinfo,可选,默认无
# 实例1:日期时间的字符串
pd.Timestamp('2019-01-01T12') # Timestamp('2019-01-01 12:00:00')
pd.Timestamp('2019-01-16 20:22:2')# Timestamp('2019-01-16 20:22:02')
# 实例2:以秒为单位转换表示Unix纪元的浮点数
pd.Timestamp(1513393355.5, unit='s')# Timestamp('2019-12-16 03:02:35.500000')
pd.Timestamp(1513393355, unit='s', tz='US/Pacific')#特定时区
# Timestamp('2019-12-15 19:02:35-0800', tz='US/Pacific')
#实例3:模仿datetime.datetime:通过位置或关键字,不能两者混合
pd.Timestamp(2019, 1, 16, 20,26,30) #Timestamp('2019-01-16 20:26:30')
pd.Timestamp(year=2019, month=1, day=16, hour=20,
minute=28, second=30, microsecond=30)#Timestamp('2019-01-16 20:28:30.000030')
'''
pandas.date_range(start=None, end=None, periods=None, freq=’D’, tz=None, normalize=False, name=None, closed=None, **kwargs)
1.start:string或datetime-like,默认值是None,表示日期的起点。
2.end:string或datetime-like,默认值是None,表示日期的终点。
3.periods:integer或None,默认值是None,表示你要从这个函数产生多少个日期索引值;如果是None的话,那么start和end必须不能为None。
4.freq:string或DateOffset,默认值是’D’,表示以自然日为单位,这个参数用来指定计时单位,比如’5H’表示每隔5个小时计算一次。
默认‘D’,可以是’H’、‘D’、‘M’、‘5H’、‘10D’
5.tz:string或None,表示时区,例如:’Asia/Hong_Kong’。
6.normalize:bool,默认值为False,如果为True的话,那么在产生时间索引值之前会先把start和end都转化为当日的午夜0点。
7.name:str,默认值为None,给返回的时间索引指定一个名字。
8.closed:string或者None,默认值为None,表示start和end这个区间端点是否包含在区间内,可以有三个值,’left’表示左闭右开区间,’right’表示左开右闭区间,None表示两边都是闭区间
'''
import pandas as pd
pd.date_range(start='1/1/2018', end='1/08/2018')
'''
DatetimeIndex(['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04', '2018-01-05', '2018-01-06', '2018-01-07', '2018-01-08'],
dtype='datetime64[ns]', freq='D')
'''
pd.date_range(start='1/1/2018', periods=8)
'''
DatetimeIndex(['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04','2018-01-05', '2018-01-06', '2018-01-07', '2018-01-08'],
dtype='datetime64[ns]', freq='D')
'''
pd.date_range(start='1/1/2018', end='1/08/2018', periods=3)
'''
DatetimeIndex(['2018-01-01 00:00:00', '2018-01-04 12:00:00','2018-01-08 00:00:00'],
dtype='datetime64[ns]', freq=None)
'''
freq参数
...+(-)+month/day/hour/min....
W-TUE星期二,其他类似
M每月最后一个日历日
M-每月最后一天
B工作日
Q-:每季度最后一个月的最后一个日历日
A-:每年指定月份的最后一个日历日
asfreq(freq,method=None,normalize=False,fill_value=None)
freq:表示计时单位,可以是DateOffest对象或字符串。
how:可以取值为start或end,默认为end,仅适用于PeriodIndex。 //start:包含区间开始;end:包含区间结束,最后一个月
normalize:布尔值,默认为False,表示是否将时间索引重置为午夜。
fill_value:用于填充缺失值,在升采样期间应用。
import pandas as pd #asfreq 时期的频率转换
period=pd.Period('2020',freq='A-DEC')
period.asfreq('D',how='start')
period.asfreq('D',how='end')
时间频率进行位移
shift(periods=1,freq=None,axis=0,fill_value=None)按所需时段数和可选的时间频率进行移位索引
若未传递freq,则在不重新调整数据的情况下移动索引。
若传递了freq(索引必须是date或datatime,否则报错NotlmplementedError),只要在索引中设置了freq或推断的_freq属性,就可以推断freq
periods:要转换的时段数。
freq:如果指定freq,则索引会位移。但数据不会重新对齐,在移动时扩展索引并保留原始数据
axis:0/1
fill_value:用于填充缺失值,在升采样期间应用
df = pd.DataFrame(np.random.rand(16).reshape((4,4)), index=pd.date_range('20210101','20210104'),
columns = list('ABCD') )
df.shift(periods=2)#所有行向下移动两行
df.shift(periods=1,axis='columns')#数值后移(滞后),设置为列
df.shift(periods=3,fill_value=0)#数值后移,NaN填充为0
df.shift(periods=3,freq='D')#对时间索引移动
per = df/df.shift(1)-1#计算变化百分比,这里计算该时间戳与上一时间戳相比的变化百分比
1.定义一个Period
p = pd.Period(2007,freq='A-DEC') #表示以12月作为结束的一整年,这里表示从2007-01-01到2017-12-31的全年2.通过加减整数可以实现对Period的移动
p+5-->20123.如果两个Period对象拥有相同频率,则它们的差就是它们之间的单位数量
pd.Period('2014',freq='A-DEC') - p4.period_range函数可用于创建规则的时期范围
rng = pd.period_range('1/1/2000','6/30/2000',freq='M') #创建从2001-01-01到2000-06-30所有月份的Period
pd.Series(np.random.randn(6),index=rng)5.PeriodIndex类的构造函数允许直接使用一组字符串表示一段时期
values = ['2001Q3','2002Q2','2003Q1']
index = pd.PeriodIndex(values,freq='Q-DEC')
index-->PeriodIndex(['2001Q3', '2002Q2', '2003Q1'], dtype='period[Q-DEC]')
'''
resample()进行重采样。
重采样(Resampling)指的是把时间序列的频度变为另一个频度的过程。把高频度的数据变为低频度叫做降采样(downsampling),把低频度变为高频度叫做增采样(upsampling)。
降采样
考虑因素:
各区间哪边是闭合的(参数:closed)
如何标记各聚合面元,用区间的开头还是末尾(参数:label)
默认使用左标签(label=‘left’),左闭合(closed='left’)
'''
import pandas as pd
ts_index = pd.date_range('2018-08-03',periods =12,freq = 'T')
DatetimeIndex([
'2018-08-03 00:00:00', '2018-08-03 00:01:00',
'2018-08-03 00:02:00', '2018-08-03 00:03:00',
'2018-08-03 00:04:00', '2018-08-03 00:05:00',
'2018-08-03 00:06:00', '2018-08-03 00:07:00',
'2018-08-03 00:08:00', '2018-08-03 00:09:00',
'2018-08-03 00:10:00', '2018-08-03 00:11:00'],
dtype='datetime64[ns]', freq='T')
ts = pd.Series(np.arange(12),index = ts_index)
2018-08-03 00:00:00 0
2018-08-03 00:01:00 1
2018-08-03 00:02:00 2
2018-08-03 00:03:00 3
2018-08-03 00:04:00 4
2018-08-03 00:05:00 5
2018-08-03 00:06:00 6
2018-08-03 00:07:00 7
2018-08-03 00:08:00 8
2018-08-03 00:09:00 9
2018-08-03 00:10:00 10
2018-08-03 00:11:00 11
Freq: T, dtype: int32
ts.resample('5min').sum()
2018-08-03 00:00:00 10
2018-08-03 00:05:00 35
2018-08-03 00:10:00 21
Freq: 5T, dtype: int32
ts.resample('5min',closed='right').sum()
2018-08-02 23:55:00 0
2018-08-03 00:00:00 15
2018-08-03 00:05:00 40
2018-08-03 00:10:00 11
Freq: 5T, dtype: int32
ts.resample('5min',closed='right',label='right').sum()
2018-08-03 00:00:00 0
2018-08-03 00:05:00 15
2018-08-03 00:10:00 40
2018-08-03 00:15:00 11
Freq: 5T, dtype: int32
pd.to_period()
pd.to_timestamp()
rng = pd.date_range('2017/1/1',periods=10,freq='M')
png = pd.period_range('2017','2018',freq='M')
print(rng)
DatetimeIndex(['2017-01-31', '2017-02-28', '2017-03-31', '2017-04-30', '2017-05-31', '2017-06-30', '2017-07-31', '2017-08-31', '2017-09-30', '2017-10-31'],
dtype='datetime64[ns]', freq='M')
print(png)
PeriodIndex(['2017-01', '2017-02', '2017-03', '2017-04', '2017-05', '2017-06','2017-07', '2017-08', '2017-09', '2017-10', '2017-11', '2017-12','2018-01'],
dtype='period[M]')
#每月最后一日,转换为每月
tsl.to_period('M').head()