顾名思义,时间序列(time series),就是由时间构成的序列,它指的是在一定时间内按照时间顺序测量的某个变量的取值序列,比如一天内的温度会随时间而发生变化,或者股票的价格会随着时间不断的波动,这里用到的一系列时间,就可以看做时间序列。时间序列包含三种应用场景,分别是:

  • 特定的时刻(timestamp),也就是时间戳;
  • 固定的日期(period),比如某年某月某日;
  • 时间间隔(interval),每隔一段时间具有规律性;

在处理时间序列的过程中,我们一般会遇到两个问题,第一,如何创建时间序列;第二,如何更改已生成时间序列的频率。 Pandas 为解决上述问题提供了一套简单、易用的方法。

下面用 Python 内置的 datetime 模块来获取当前时间,通过该模块提供的now()方法即可实现。

  1. from datetime import datetime
  2. #数据类型为datetime
  3. print(datetime.now())

输出结果:

2020-12-16 16:36:18.791297

创建时间戳

TimeStamp(时间戳) 是时间序列中的最基本的数据类型,它将数值与时间点完美结合在一起。Pandas 使用下列方法创建时间戳:

  1. import pandas as pd
  2. print (pd.Timestamp('2017-03-01'))

输出结果:

2017-03-01 00:00:00

同样,可以将整型或浮点型表示的时间转换为时间戳。默认的单位是纳秒(时间戳单位),示例如下:

  1. import pandas as pd
  2. print(pd.Timestamp(1587687255,unit='s'))

输出结果:

2022-03-19 14:26:39

创建时间范围

通过 date_range() 方法可以创建某段连续的时间或者固定间隔的时间时间段。该函数提供了三个参数,分别是:

  • start:开始时间
  • end:结束时间
  • freq:时间频率,默认为 "D"(天)

示例如下:

  1. import pandas as pd
  2. #freq表示时间频率,每30min变化一次
  3. print(pd.date_range("9:00", "18:10", freq="30min").time)

输出结果:

[datetime.time(9, 0) datetime.time(9, 30) datetime.time(10, 0)
datetime.time(10, 30) datetime.time(11, 0) datetime.time(11, 30)
datetime.time(12, 0) datetime.time(12, 30) datetime.time(13, 0)
datetime.time(13, 30) datetime.time(14, 0) datetime.time(14, 30)
datetime.time(15, 0) datetime.time(15, 30) datetime.time(16, 0)
datetime.time(16, 30) datetime.time(17, 0) datetime.time(17, 30)
datetime.time(18, 0)]

更改时间频率

  1. import pandas as pd
  2. #修改为按小时
  3. print(pd.date_range("6:10", "11:45", freq="H").time)

输出结果:

[datetime.time(6, 10) datetime.time(7, 10) datetime.time(8, 10)
datetime.time(9, 10) datetime.time(10, 10) datetime.time(11, 10)]

转化为时间戳

您可以使用 to_datetime() 函数将 series 或 list 转换为日期对象,其中 list 会转换为DatetimeIndex。示例如下:

  1. import pandas as pd
  2. print(pd.to_datetime(pd.Series(['Jun 3, 2020','2020-12-10', None])))

输出结果:

  1. 0 2020-06-03
  2. 1 2020-12-10
  3. 2 NaT
  4. dtype: datetime64[ns]

注意:NaT 表示的不是时间 ,它等效于 NaN。

最后再来看一个示例:

  1. import pandas as pd
  2. #传入list,生成Datetimeindex
  3. print(pd.to_datetime(['Jun 31, 2020','2020-12-10', None]))

输出结果:

DatetimeIndex(['2020-06-03', '2020-12-10', 'NaT'], dtype='datetime64[ns]', freq=None)

频率和周期转换

Time Periods 表示时间跨度,一段时间周期,它被定义在 Pandas Periods 类中,通过该类提供的方法可以实现将频率转换为周期。比如 Periods() 方法,可以将频率 "M"(月)转换为 Period(时间段)。

下面示例,使用 asfreq() 和 start 参数,打印 "01" ,若使用 end 参数,则打印 "31"。示例如下:

  1. import pandas as pd
  2. x = pd.Period('2014', freq='M')
  3. #start参数
  4. x.asfreq('D', 'start')
  5. #end参数
  6. x.asfreq('D', 'end')

输出结果:

Period('2014-01-01', 'D')
Period('2014-01-31', 'D')

对于常用的时间序列频率,Pandas 为其规定了一些字符串别名,我们将这些别名称为“offset(偏移量)”。如下表所示:

别名 描述 别名 描述
B 工作日频率 BQS 工作季度开始频率
D 日历日频率 A 年终频率
W 每周频率 BA 工作年度结束频率
M 月末频率 BAS 工作年度开始频率
SM 半月结束频率 BH 营业时间频率
BM 工作月结束频率 H 小时频率
MS 月开始频率 T,min 每分钟频率
SMS 半月开始频率 S 每秒钟频率
BMS 工作月开始频率 L,ms 毫秒
Q 季末频率 U,us 微妙
BQ 工作季度结束频率 N 纳秒
QS 季度开始频率    

时间周期计算

周期计算,指的是对时间周期进行算术运算,所有的操作将在“频率”的基础上执行。

  1. import pandas as pd
  2. #S表示秒
  3. x = pd.Period('2014', freq='S')
  4. x

输出结果:

Period('2014-01-01 00:00:00', 'S')

执行计算示例:

  1. import pandas as pd
  2. x = pd.Period('2014', freq='S')
  3. #加1s的时间
  4. print(x+1)

输出结果:

Period('2014-01-01 00:00:01', 'S')

再看一组完整的示例:

  1. #定义时期period,默认freq="Y"年份
  2. p1=pd.Period('2020')
  3. p2=pd.Period('2019')
  4. #使用f''格式化输出
  5. print(f'p1={p1}年')
  6. print(f'p2={p2}年')
  7. print(f'p1和p2间隔{p1-p2}年')
  8. #f''表示字符串格式化输出
  9. print(f'五年前是{p1-5}年')

输出结果:

p1=2020年
p2=2019年
p1和p2间隔<YearEnd: month=12>年
五年前是2015年

创建时间周期

我们可以使用 period_range() 方法来创建时间周期范围。示例如下:

  1. import pandas as pd
  2. #Y表示年
  3. p = pd.period_range('2016','2018', freq='Y')
  4. p

输出结果:

PeriodIndex(['2016', '2017', '2018'], dtype='period[A-DEC]', freq='A-DEC')

时间序列转换

如果想要把字符串日期转换为 Period,首先需要将字符串转换为日期格式,然后再将日期转换为 Period。示例如下:

  1. # 创建时间序列
  2. index=pd.date_range("2020-03-17","2020-03-30",freq="1.5H")
  3. #随机选取4个互不相同的数
  4. loc=np.random.choice(np.arange(len(index)),size=4,replace=False)
  5. loc.sort()
  6. ts_index=index[loc]
  7. ts_index
  8. pd_index=ts_index.to_periods('D')
  9. pd_index()

输出结果:

DatetimeIndex(['2020-03-17 12:00:00', '2020-03-22 04:30:00',
'2020-03-27 03:00:00', '2020-03-30 00:00:00'],
dtype='datetime64[ns]', freq=None) PeriodIndex(['2020-03-17', '2020-03-19', '2020-03-19', '2020-03-27'], dtype='period[D]', freq='D')

使用 to_timestamp() 能够将 Period 时期转换为时间戳(timestamp),示例如下:

  1. import pandas as pd
  2. p1=pd.Periods("2020-2-3")
  3. p1.to_timestamp()

输出结果:

Timestamp('2020-02-03 00:00:00')

创建日期范围

Pandas 提供了用来创建日期序列的函数 date_range(),该函数的默认频率为 "D", 也就是“天”。日期序列只包含年、月、日,不包含时、分、秒。

下面是一组简单的示例,如下所示:

  1. import pandas as pd
  2. print(pd.date_range('12/15/2020', periods=10))

输出结果:

DatetimeIndex(['2020-12-15', '2020-12-16', '2020-12-17', '2020-12-18',
'2020-12-19', '2020-12-20', '2020-12-21', '2020-12-22',
'2020-12-23', '2020-12-24'],
dtype='datetime64[ns]', freq='D')

当我们使用 date_range() 来创建日期范围时,该函数包含结束的日期,用数学术语来说就是区间左闭右闭,即包含起始值,也包含结束值。示例如下:

  1. import pandas as pd
  2. #建议使用Python的datetime模块创建时间
  3. start = pd.datetime(2019, 1, 1)
  4. end = pd.datetime(2019, 1, 5)
  5. print pd.date_range(start,end)

输出结果:

DatetimeIndex(['2019-01-01', '2019-01-02', '2019-01-03', '2019-01-04','2019-01-05']
,dtype='datetime64[ns]', freq='D')

更改日频率

使用下列方法可以修改频率,比如按“天”为按“月”,示例如下:

  1. import pandas as pd
  2. print(pd.date_range('12/15/2011', periods=5,freq='M'))

输出结果:

DatetimeIndex(['2020-12-31', '2021-01-31', '2021-02-28', '2021-03-31',
               '2021-04-30'],dtype='datetime64[ns]', freq='M')

工作日时间

bdate_range() 表示创建工作日的日期范围,它与 date_range() 不同,它不包括周六、周日。

  1. import pandas as pd
  2. print(pd.date_range('11/25/2020', periods=8))

输出结果:

DatetimeIndex(['2020-11-25', '2020-11-26', '2020-11-27', '2020-11-28','2020-11-29', '2020-11-30', '2020-12-01', '2020-12-02'],dtype='datetime64[ns]', freq='D')

上述方法中,date_range() 默认频率是日历日,而 bdate_range() 的默认频率是工作日。

----------------------------------------------------------------‘’

日期格式化符号

在对时间进行格式化处理时,它们都有固定的表示格式,比如小时的格式化符号为%H ,分钟简写为%M ,秒简写为%S。下表对常用的日期格式化符号做了总结:

日期格式化符号
符号 说明
%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(000-9999)
%m 月份(01-12)
%d 月内中的一天(0-31)
%H 24小时制小时数(0-23)
%I 12小时制小时数(01-12)
%M 分钟数(00=59)
%S 秒(00-59)
%a 本地英文缩写星期名称
%A 本地英文完整星期名称
%b 本地缩写英文的月份名称
%B 本地完整英文的月份名称
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%Z 当前时区的名称
%U 一年中的星期数(00-53)星期天为星期的开始
%j 年内的一天(001-366)
%c 本地相应的日期表示和时间表示

Python处理

Python 内置的 strptime() 方法能够将字符串日期转换为 datetime 类型,下面看一组示例:

  1. from datetime import datetime
  2. #将日期定义为字符串
  3. date_str1 = 'Wednesday, July 18, 2020'
  4. date_str2 = '18/7/20'
  5. date_str3 = '18-07-2020'
  6. #将日期转化为datetime对象
  7. dmy_dt1 = datetime.strptime(date_str1, '%A,%B%d,%Y')
  8. dmy_dt2 = datetime.strptime(date_str2, '%d/%m/%y')
  9. dmy_dt3 = datetime.strptime(date_str3, '%d-%m-%Y')
  10. #处理为相同格式,并打印输出
  11. print(dmy_dt1)
  12. print(dmy_dt2)
  13. print(dmy_dt3)

输出结果:

2020-07-18 00:00:00
2020-07-18 00:00:00
2020-07-18 00:00:00

注意:strftime() 可以将 datetime 类型转换为字符串类型,恰好与 strptime() 相反。

Pandas处理

除了使用 Python 内置的 strptime() 方法外,你还可以使用 Pandas 模块的 pd.to_datetime() 和 pd.DatetimeIndex() 进行转换。

1) to_datetime()

通过 to_datetime() 直接转换为 datetime 类型

  1. import pandas as pd
  2. import numpy as np
  3. date = ['2012-05-06 11:00:00','2012-05-16 11:00:00']
  4. pd_date=pd.to_datetime(date)
  5. df=pd.Series(np.random.randn(2),index=pd_date)

输出结果:

2012-05-06 11:00:00    0.189865
2012-05-16 11:00:00 1.052456
dtype: float64

2) DatetimeIndex()

使用 Datetimeindex() 函数设置时间序,示例如下:

  1. date = pd.DatetimeIndex(['1/1/2008', '1/2/2008', '1/3/2008', '1/4/2008', '1/5/2008'])
  2. dt = pd.Series(np.random.randn(5),index = date)
  3. print(dt)

输出结果:

2008-01-01    1.965619
2008-01-02 -2.897374
2008-01-03 0.625929
2008-01-04 1.204926
2008-01-05 1.755680
dtype: float6-----------------------------------------------------------
Timedelta 表示时间差(或者时间增量),我们可以使用不同的时间单位来表示它,比如,天、小时、分、秒。时间差的最终的结果可以是正时间差,也可以是负时间差。

本节主要介绍创建 Timedelta (时间差)的方法以及与时间差相关的运算法则。

字符串

通过传递字符串可以创建 Timedelta 对象,示例如下:
  1. import pandas as pd
  2. print(pd.Timedelta('5 days 8 hours 6 minutes 59 seconds'))
输出结果:

5 days 08:06:59

整数

通过传递整数值和unit参数也可以创建一个 Timedelta 对象。
  1. import pandas as pd
  2. print(pd.Timedelta(19,unit='h'))
输出结果:

0 days 19:00:00

数据偏移量

数据偏移量, 比如,周(weeks)、天(days)、小时(hours)、分钟(minutes)、秒(milliseconds)、毫秒、微秒、纳秒都可以使用。
  1. import pandas as pd
  2. print (pd.Timedelta(days=2,hours=6))
输出结果:

2 days 06:00:00

to_timedelta()

您可以使用pd.to_timedelta()方法,将具有 timedelta 格式的值 (标量、数组、列表或 Series)转换为 Timedelta 类型。如果输入是 Series,则返回 Series;如果输入是标量,则返回值也为标量,其他情况输出 TimedeltaIndex。示例如下:
  1. import pandas as pd
  2. print(pd.to_timedelta(['1 days 06:05:01.00003', '15.5us', 'nan']))
  3. print(pd.to_timedelta(np.arange(5), unit='s'))
输出结果:
TimedeltaIndex(['1 days 06:05:01.000030', '0 days 00:00:00.000015', NaT],dtype='timedelta64[ns]', freq=None)

TimedeltaIndex(['0 days 00:00:00', '0 days 00:00:01', '0 days 00:00:02','0 days 00:00:03',
'0 days 00:00:04'],dtype='timedelta64[ns]', freq=None)

算术操作

通过对datetime64[ns]类型的时间序列或时间戳做算术运算,其运算结果依然是datetime64[ns]数据类型。接下来,我们创建一个带有 Timedelta 与 datetime 的 DataFrame 对象,并对其做一些算术运算。
  1. import pandas as pd
  2. s = pd.Series(pd.date_range('2020-1-1', periods=5, freq='D'))
  3. #推导式用法
  4. td = pd.Series([ pd.Timedelta(days=i) for i in range(5)])
  5. df = pd.DataFrame(dict(A = s, B = td))
  6. print(df)
输出结果:
           A      B
0 2020-01-01 0 days
1 2020-01-02 1 days
2 2020-01-03 2 days
3 2020-01-04 3 days
4 2020-01-05 4 days

加法运算

  1. import pandas as pd
  2. s = pd.Series(pd.date_range('20120-1-1', periods=3, freq='D'))
  3. td = pd.Series([ pd.Timedelta(days=i) for i in range(3) ])
  4. df = pd.DataFrame(dict(A = s, B = td))
  5. #加法运算
  6. df['C']=df['A']+df['B']
  7. print(df)
输出结果:
           A      B          C
0 2020-01-01 0 days 2020-01-01
1 2020-01-02 1 days 2020-01-03
2 2020-01-03 2 days 2020-01-05

减法运算

  1. import pandas as pd
  2. s = pd.Series(pd.date_range('2012-1-1', periods=3, freq='D'))
  3. td = pd.Series([ pd.Timedelta(days=i) for i in range(3) ])
  4. df = pd.DataFrame(dict(A = s, B = td))
  5. df['C']=df['A']+df['B']
  6. df['D']=df['C']-df['B']
  7. print(df)
输出结果:
           A      B          C          D
0 2019-01-01 0 days 2019-01-01 2019-01-01
1 2019-01-02 1 days 2019-01-03 2019-01-02
2 2019-01-03 2 days 2019-01-05 2019-01-03
------------------------------------------------------

pandas之时间操作的更多相关文章

  1. Python基础 | 日期时间操作

    目录 获取时间 时间映射 格式转换 字符串转日期 日期转字符串 unixtime 时间计算 时间偏移 时间差 "日期时间数据"作为三大基础数据类型之一,在数据分析中会经常遇到. 本 ...

  2. Java Calendar 类的时间操作

    Java Calendar 类的时间操作 标签: javaCalendar时间Date 2013-07-30 17:53 140401人阅读 评论(7) 收藏 举报 分类: 所有(165) Java ...

  3. paip.日期时间操作以及时间戳uapi php java python 总结

    paip.日期时间操作以及时间戳uapi php java python 总结 ///uapi Date 函数 | Day 函数 | Hour 函数 | Minute 函数 | Month 函数 | ...

  4. [时间操作] C#DateFormat时间帮助类 (转载)

    点击下载 DateFormat.rar 主要功能如下 返回每月的第一天和最后一天 看下面代码吧 /// <summary> /// 类说明:时间操作类 /// 编 码 人:苏飞 /// 联 ...

  5. Flex时间操作

    小弟是Flex新手,最近一段时间领导要求使用Flex开发B/S的一些项目,需要用到时间上的一些操作.上网查询一番好多人都说不好操作,有的甚至非常麻烦.基于此,小弟整理了一些关于Flex时间操作的经验, ...

  6. JAVA中的时间操作

    java中的时间操作不外乎这四种情况: 1.获取当前时间 2.获取某个时间的某种格式 3.设置时间 4.时间的运算 好,下面就针对这四种情况,一个一个搞定. 一.获取当前时间 有两种方式可以获得,第一 ...

  7. Mysql 时间操作

    Mysql 时间操作(当天,昨天,7天,30天,半年,全年,季度) 1 . 查看当天日期 select current_date(); 2. 查看当天时间 select current_time(); ...

  8. 小笔记:Timer定时间隔时间操作

    小笔记:Timer定时间隔时间操作,后面有时间再补充和完善: public class TimingSvc { /// <summary> /// 定时器,执行定时任务 /// </ ...

  9. java时间操作

    这篇讲的也很专业:http://soft.zdnet.com.cn/software_zone/2007/1129/660028.shtml java中的时间操作不外乎这四种情况: 1.获取当前时间 ...

  10. pandas的apply操作

    pandas的apply操作类似于Scala的udf一样方便,假设存在如下dataframe: id_part pred pred_class v_id 0 d [0.722817, 0.650064 ...

随机推荐

  1. 反序列化 sqlserver 中的 sysdiagrams,找到其中包含的表的信息

    转载于:Script SQL Server 2005 diagrams to a file - CodeProject /** <summary> Based on ufn_Varbina ...

  2. springboot项目记录2用户注册功能

    七.注册-业务层 7.1规划异常 7.1.1用户在进行注册的时候,可能会产生用户名被占用的错误,抛出一个异常: RuntimeException异常,作为该异常的子类,然后再去定义具体的异常类型继承这 ...

  3. Restful Fast Request 添加前置脚本,实现不同环境免设置token 直接请求

    idea安装Restful Fast Request插件后,进行如下设置,并打开 项目全局参数 对话框 进入前置脚本 tab 编写如下groovy脚本代码(插件脚本语言默认支持groovy,该语言被称 ...

  4. Vuex的核心State

    State提供唯一的公共数据源,所有共享的数据都要统一放到 Store的 State 中进行存储. import Vue from 'vue' import Vuex from 'vuex' Vue. ...

  5. cesium 入门指南

    最近拿到了几份offer,经过这次找工作发现自己最近脱节挺严重,为了后续的职业发展,决定开始书写博客记录自己的努力. cesium属于 跨平台.跨浏览器的展现三维地球.地图的JavaScript库. ...

  6. Jmeter检查点

    一.Response Assertion(响应断言) 1. 添加响应断言 对Web请求的响应结果进行验证,Response Assertion配置参数 2. 输入需要匹配的字符串 此处对于访问Baid ...

  7. 容器数据库(CDB)和传统的非容器数据库的区别

    传统的非容器数据库在系统元数据和实例资源没有进行任何共享.容器数据库把 Oracle 提供的元数据.后台进程以及内存结构进行共享,把每个部门数据库的存储结构以 PDB 的形式独立出来,从而实现了系统资 ...

  8. centos7部署teleport堡垒机

    Centos7.9部署Teleport堡垒机 简介 Teleport是一款简单易用的开源堡垒机系统,具有小巧.易用的特点,支持 RDP/SSH/SFTP/Telnet 协议的远程连接和审计管理.Tel ...

  9. [C#]索引指示器

    参考代码: using System; namespace IndexerDemo { class StuInfo { public string Name; public string[] CouN ...

  10. centos7中Firefox安装Flash插件

    第一步:先下载好Flash插件安装包,可以到Adobe官网下载.因为是linux 64位系统,所以要下个匹配的,我下载的是flash_player_npapi_linux.x86_64.tar.gz, ...