pandas时间处理

目录

一:时间处理

 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)
   

 1.常用频率和日期偏移量:pandas时间处理_第1张图片

 

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()

2.pandas.Series.dt对象能够返回的信息有:

pandas时间处理_第2张图片

 

二.格式化日期

pandas时间处理_第3张图片

 

 

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()

 1.pandas中有四种时间类型:

Date times : 日期和时间,可以带时区。和标准库中的 datetime.datetime 类似。
Time deltas: 绝对持续时间,和 标准库中的 datetime.timedelta 类似。
Time spans: 由时间点及其关联的频率定义的时间跨度。
Date offsets:基于日历计算的时间 和 dateutil.relativedelta.relativedelta 类似。

2.时间序列TimeSries

# 生成时间数据,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,

 

3.时间索引的特性


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生成新的切片,默认值向下填充(以下一个非空值为准)

4.时间格式转换:


1.strptime与strftime

时间格式转换
代码	说明
%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)

2.pd.Timestamp:

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')

3.pandas.date_range()

'''
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-:每年指定月份的最后一个日历日

 

三:Pandas中的时期的频率转换

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')

1.Shift时间频率进行位移

时间频率进行位移
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#计算变化百分比,这里计算该时间戳与上一时间戳相比的变化百分比

2.period()

1.定义一个Period
p = pd.Period(2007,freq='A-DEC') #表示以12月作为结束的一整年,这里表示从2007-01-01到2017-12-31的全年

2.通过加减整数可以实现对Period的移动
p+5-->2012

3.如果两个Period对象拥有相同频率,则它们的差就是它们之间的单位数量
pd.Period('2014',freq='A-DEC') - p

4.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]')

3.resample()

'''
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

4.时间戳和时期之间的转换

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()

你可能感兴趣的:(pandas,python,开发语言,数据分析,pycharm)