时间序列--日期的范围、频率及移动

pandas中的时间序列一般被认为是不规则的,也就是说,没有固定的频率。但pandas有一整套标准时间序列频率以及用于重采样、频率推断、生成固定频率日期范围的工具。例如将一个时间序列转换为固定频率的时间序列,只需要调用resample即可。

频率的转换(或重采样)是一个大的主题,这里先介绍如何使用基本的频率。

1.1 生成日期范围

pandas.date_range()可用于生成指定长度的DatetimeIndex。

1 >>> index = pd.date_range(‘1/1/2020‘, ‘1/10/2020‘)
2 >>> index
3 DatetimeIndex([‘2020-01-01‘, ‘2020-01-02‘, ‘2020-01-03‘, ‘2020-01-04‘,
4                ‘2020-01-05‘, ‘2020-01-06‘, ‘2020-01-07‘, ‘2020-01-08‘,
5                ‘2020-01-09‘, ‘2020-01-10‘],
6               dtype=‘datetime64[ns]‘, freq=‘D‘)
7 >>>

默认情况下,date_range会产生按天计算的时间点,如果只传入起始或结束日期。那就还得传入一个表示一段时间的数字。

 1 >>> pd.date_range(start=‘1/1/2020‘, periods=20)
 2 DatetimeIndex([‘2020-01-01‘, ‘2020-01-02‘, ‘2020-01-03‘, ‘2020-01-04‘,
 3                ‘2020-01-05‘, ‘2020-01-06‘, ‘2020-01-07‘, ‘2020-01-08‘,
 4                ‘2020-01-09‘, ‘2020-01-10‘, ‘2020-01-11‘, ‘2020-01-12‘,
 5                ‘2020-01-13‘, ‘2020-01-14‘, ‘2020-01-15‘, ‘2020-01-16‘,
 6                ‘2020-01-17‘, ‘2020-01-18‘, ‘2020-01-19‘, ‘2020-01-20‘],
 7               dtype=‘datetime64[ns]‘, freq=‘D‘)
 8 >>> pd.date_range(end=‘1/20/2020‘, periods=20)
 9 DatetimeIndex([‘2020-01-01‘, ‘2020-01-02‘, ‘2020-01-03‘, ‘2020-01-04‘,
10                ‘2020-01-05‘, ‘2020-01-06‘, ‘2020-01-07‘, ‘2020-01-08‘,
11                ‘2020-01-09‘, ‘2020-01-10‘, ‘2020-01-11‘, ‘2020-01-12‘,
12                ‘2020-01-13‘, ‘2020-01-14‘, ‘2020-01-15‘, ‘2020-01-16‘,
13                ‘2020-01-17‘, ‘2020-01-18‘, ‘2020-01-19‘, ‘2020-01-20‘],
14               dtype=‘datetime64[ns]‘, freq=‘D‘)
15 >>>

起始和结束日期定义了日期索引的严格边界。例如,如果你想要生成由每月最后一个工作日组成的日期索引,可以传入“BM”频率(表示business end of month),这样只会包含时间间隔内(或刚好在边界上)符合频率要求的日期。

1 >>> pd.date_range(‘1/1/2000‘, ‘12/1/2000‘, freq=‘BM‘)
2 DatetimeIndex([‘2000-01-31‘, ‘2000-02-29‘, ‘2000-03-31‘, ‘2000-04-28‘,
3                ‘2000-05-31‘, ‘2000-06-30‘, ‘2000-07-31‘, ‘2000-08-31‘,
4                ‘2000-09-29‘, ‘2000-10-31‘, ‘2000-11-30‘],
5               dtype=‘datetime64[ns]‘, freq=‘BM‘)
6 >>>

date_range默认会保留起始和结束时间戳的时间信息。

1 >>> pd.date_range(‘5/2/2012 12:56:31‘, periods=5)
2 DatetimeIndex([‘2012-05-02 12:56:31‘, ‘2012-05-03 12:56:31‘,
3                ‘2012-05-04 12:56:31‘, ‘2012-05-05 12:56:31‘,
4                ‘2012-05-06 12:56:31‘],
5               dtype=‘datetime64[ns]‘, freq=‘D‘)

有时,虽然起始和结束日期都带有时间信息,但希望产生一组被规范化(normalize)到午夜的时间戳,normalize选项即可实现该功能。

1 >>> pd.date_range(‘5/2/2012 12:56:31‘, periods=5, normalize=True)
2 DatetimeIndex([‘2012-05-02‘, ‘2012-05-03‘, ‘2012-05-04‘, ‘2012-05-05‘,
3                ‘2012-05-06‘],
4               dtype=‘datetime64[ns]‘, freq=‘D‘) 

1.2  频率与日期偏移量

pandas的频率由一个基础频率(base frequency)和一个乘数组成的。基础频率通常以一个字符串别名表示,比如“M”表示每月,“H”表示每小时。对于每个基础频率,都有一个被称为日期偏移量(date offset)的对象与之对应。如,按小时计算的频率可以用Hour类表示。

1 >>> from pandas.tseries.offsets import Hour, Minute
2 >>> hour = Hour()
3 >>> hour
4 <Hour>
5 >>> four_hours = Hour(4)  #定义偏移量的倍数
6 >>> four_hours
7 <4 * Hours>

一般来说,无需显示创建这样的对象,只需要使用诸如“H”或“4H”这样的字符串别名即可。在基础频率前放一个整数即可创建倍数。

 1 >>> pd.date_range(‘1/1/2020‘, ‘1/3/2020 23:59‘, freq=‘4H‘)
 2 DatetimeIndex([‘2020-01-01 00:00:00‘, ‘2020-01-01 04:00:00‘,
 3                ‘2020-01-01 08:00:00‘, ‘2020-01-01 12:00:00‘,
 4                ‘2020-01-01 16:00:00‘, ‘2020-01-01 20:00:00‘,
 5                ‘2020-01-02 00:00:00‘, ‘2020-01-02 04:00:00‘,
 6                ‘2020-01-02 08:00:00‘, ‘2020-01-02 12:00:00‘,
 7                ‘2020-01-02 16:00:00‘, ‘2020-01-02 20:00:00‘,
 8                ‘2020-01-03 00:00:00‘, ‘2020-01-03 04:00:00‘,
 9                ‘2020-01-03 08:00:00‘, ‘2020-01-03 12:00:00‘,
10                ‘2020-01-03 16:00:00‘, ‘2020-01-03 20:00:00‘],
11               dtype=‘datetime64[ns]‘, freq=‘4H‘)

大部分偏移量对象可通过加法进行连接。

1 >>> Hour(2) + Minute(30)
2 <150 * Minutes>

同理,也可以传入频率字符串,这种字符串可以被高效的解析为等效的表达式。

1 >>> pd.date_range(‘1/1/2020‘, periods=10, freq=‘1h30min‘)
2 DatetimeIndex([‘2020-01-01 00:00:00‘, ‘2020-01-01 01:30:00‘,
3                ‘2020-01-01 03:00:00‘, ‘2020-01-01 04:30:00‘,
4                ‘2020-01-01 06:00:00‘, ‘2020-01-01 07:30:00‘,
5                ‘2020-01-01 09:00:00‘, ‘2020-01-01 10:30:00‘,
6                ‘2020-01-01 12:00:00‘, ‘2020-01-01 13:30:00‘],
7               dtype=‘datetime64[ns]‘, freq=‘90T‘)

有些频率说描述的时间点并不是均匀分隔的,例如:“M”(日历月末)和“BM”(每月最后一个工作日)就取决于每月的天数。对于后者,还要考虑月末是不是周末。我们将这些称为瞄点偏移量(anchored offset)。下表是pandas中频率代码和日期偏移量类。


别名


偏移量类型


说明


D


Day


每日历日


B


BusinessDay


每工作日


H


Hour


每小时


T或min


Minute


每分


S


Second


每秒


L或ms


Milli


每毫秒(即每千分之一秒)


Y


Micro


每微妙(即每百万分之一秒)


M


MonthEnd


每月最后一个日历日


BM


BusinessMonthEnd


每月最后一个工作日


MS


MonthBegin


每月第一个日历日


BMS


BusinessMonthBegin


每月第一个工作日


W-MON、W-TUE…


Week


从指定的星期几(MON、TUE、WED、THU、FRI、SAT、SUM)开始算起,每周


WOM-1MON、WOM-2MON…


WeekOfMonth


产生每月第一、第二、第三或第四周的星期几。例如,WOM-3FRI表示每月第三个星期五


Q-JAN、Q-FEB…


QuarterEnd


对于以指定月份(JAN、FEB、MAR、APR、MAY、JUN、JUL、AUG、SEP、OCT、NOV、DEC)结束的年度,每季度最后一月的最后一个日历日


BQ-JAN、BQ-FEB…


BusinessQuarterEnd


对于以指定月份结束的年度,每季度最后一月的最后一个工作日


QS-JAN、QS-FEB…


QuarterBegin


对于以指定月份结束的年度,么季度最后一月的第一个日历日


BQS-JAN、BQS-FEB…


BusinessQuarterBegin


对于以指定月份结束的年度。每季度最后一月的第一个工作日


A-JAN、A-FEB…


YearEnd


每年指定月份的最后一个日历日


BA-JAN、BA-FEB…


BusinessYearEnd


每年指定月份的最后一个工作日


AS-JAN、AS-FEB…


YearBegin


每年指定月份的第一个日历日


BAS-JAN、BAS-FEB…


BusinessYearBegin


每年指定月份的第一个工作日

WOM日期:WOM(Week Of Month)是一种很实用的频率类。它使你能够获得诸如“每月第三个星期五”之类的日期:

1 >>> rng = pd.date_range(‘1/1/2020‘, ‘9/1/2020‘, freq=‘WOM-3FRI‘)
2 >>> list(rng)
3 [Timestamp(‘2020-01-17 00:00:00‘, freq=‘WOM-3FRI‘), Timestamp(‘2020-02-21 00:00:00‘, freq=‘WOM-3FRI‘), Timestamp(‘2020-03-20 00:00:00‘, freq=‘WOM-3FRI‘), Timestamp(‘2020-04-17
4 00:00:00‘, freq=‘WOM-3FRI‘), Timestamp(‘2020-05-15 00:00:00‘, freq=‘WOM-3FRI‘), Timestamp(‘2020-06-19 00:00:00‘, freq=‘WOM-3FRI‘), Timestamp(‘2020-07-17 00:00:00‘, freq=‘WOM-3FRI‘), Timestamp(‘2020-08-21 00:00:00‘, freq=‘WOM-3FRI‘)]
5 >>>

1.3  移动(超前或滞后)数据

移动(shifting)指的是沿着时间轴将数据前移或者后移。Series和DataFrame都有一个shift方法用于执行单纯的前移或后移操作,保持索引不变。

 1 >>> ts = pd.Series(np.random.randn(4), index=pd.date_range(‘1/1/2000‘, periods=4, freq=‘M‘))
 2 >>> ts
 3 2000-01-31   -1.341160
 4 2000-02-29    1.146953
 5 2000-03-31   -1.434801
 6 2000-04-30   -1.175278
 7 Freq: M, dtype: float64
 8 >>> ts.shift(2)
 9 2000-01-31         NaN
10 2000-02-29         NaN
11 2000-03-31   -1.341160
12 2000-04-30    1.146953
13 Freq: M, dtype: float64
14 >>> ts.shift(-2)
15 2000-01-31   -1.434801
16 2000-02-29   -1.175278
17 2000-03-31         NaN
18 2000-04-30         NaN
19 Freq: M, dtype: float64
20 >>>

shift通常用于计算一个时间序列或多个时间序列(如DataFrame的列)中的百分比变化。可以这样表达:ts/ts.shift(1) – 1。

由于单纯的移位操作不会修改索引,所以部分数据会被丢弃。因此,如果频率已知,则可以将其传给shift以便实现对时间戳进行移位而不是对数据进行简单移位。

 1 >>> ts
 2 2000-01-31   -1.341160
 3 2000-02-29    1.146953
 4 2000-03-31   -1.434801
 5 2000-04-30   -1.175278
 6 Freq: M, dtype: float64
 7 >>> ts.shift(2, freq=‘M‘)
 8 2000-03-31   -1.341160
 9 2000-04-30    1.146953
10 2000-05-31   -1.434801
11 2000-06-30   -1.175278
12 Freq: M, dtype: float64
13 >>> ts.shift(3, freq=‘D‘)
14 2000-02-03   -1.341160
15 2000-03-03    1.146953
16 2000-04-03   -1.434801
17 2000-05-03   -1.175278
18 dtype: float64
19 >>> ts.shift(1, freq=‘3D‘)
20 2000-02-03   -1.341160
21 2000-03-03    1.146953
22 2000-04-03   -1.434801
23 2000-05-03   -1.175278
24 dtype: float64
25 >>> ts.shift(1, freq=‘90T‘)
26 2000-01-31 01:30:00   -1.341160
27 2000-02-29 01:30:00    1.146953
28 2000-03-31 01:30:00   -1.434801
29 2000-04-30 01:30:00   -1.175278
30 Freq: M, dtype: float64
31 >>> 

1.4  通过偏移量对日期进行位移

pandas的日期偏移量还可以对用在datetime或timestamp对象上。

如果加的是锚点偏移量(比如MonthEnd),第一次增量会将原日期向前滚动到符合频率规则的下一个日期。

通过锚点偏移量的rollforward和rollback方法,可以显示的将日期向前或先后“滚动”。

 1 >>> from pandas.tseries.offsets import Day, MonthEnd
 2 >>> now = datetime(2011, 11, 17)
 3 >>> now + 3*Day()  #增加锚点偏移量
 4 Timestamp(‘2011-11-20 00:00:00‘)
 5 >>> now + MonthEnd()
 6 Timestamp(‘2011-11-30 00:00:00‘)
 7 >>> now + MonthEnd(2)
 8 Timestamp(‘2011-12-31 00:00:00‘)
 9 >>> offset = MonthEnd()
10 >>> offset.rollforward(now)  #前滚
11 Timestamp(‘2011-11-30 00:00:00‘)
12 >>> offset.rollback(now)    #后滚
13 Timestamp(‘2011-10-31 00:00:00‘)

日期偏移量还有一个巧妙地用法,即结合groupby使用这两个“滚动”方法:

 1 >>> ts = pd.Series(np.random.randn(20), index=pd.date_range(‘1/15/2000‘, periods=20, freq=‘4d‘))
 2 >>> ts.groupby(offset.rollforward).mean()
 3 2000-01-31   -0.472525
 4 2000-02-29   -0.328598
 5 2000-03-31   -0.620547
 6 dtype: float64
 7 >>> ts
 8 2000-01-15    1.318127
 9 2000-01-19   -1.589067
10 2000-01-23   -1.157066
11 2000-01-27   -0.621659
12 2000-01-31   -0.312961
13 2000-02-04   -0.839835
14 2000-02-08    0.886033
15 2000-02-12   -0.478009
16 2000-02-16   -0.383263
17 2000-02-20    1.837059
18 2000-02-24   -1.343584
19 2000-02-28   -1.978589
20 2000-03-03   -1.372423
21 2000-03-07   -0.837760
22 2000-03-11   -0.329621
23 2000-03-15   -0.237106
24 2000-03-19   -0.596162
25 2000-03-23   -1.020840
26 2000-03-27   -0.037938
27 2000-03-31   -0.532527
28 Freq: 4D, dtype: float64

原文地址:https://www.cnblogs.com/mrlayfolk/p/12268518.html

时间: 2024-10-04 11:59:15

时间序列--日期的范围、频率及移动的相关文章

时间序列--日期和时间数据类型及工具

时间序列(time series)数据是一种重要得结构化数据形式,在多个时间点观察或测量到得任何事物都可以形成一段时间序列,很多时间序列是固定频率的.也就是说,数据点是根据某种规律定期出现的(比如15s.5min.1mont).时间序列也可以是不定期的.时间序列的意义取决于具体的应用场景,主要有以下几种: 时间戳(timestamp),特定的时刻 固定日期(period),如2007年1月或2010年全年 时间间隔(interval),由起始和结束时间戳表示,时期(period)可以被看作间隔(

时间序列基础

一.时间戳索引DatetimeIndex 生成20个DatetimeIndex from datetime import datetime dates = pd.date_range(start='2019-04-01',periods=20) dates 用这20个索引作为ts的索引 ts = pd.Series(np.random.randn(20),index=dates) ts 不同索引的时间序列之间的算术运算在日期上自动对齐 ts + ts[::2] pandas使用numpy的dat

pandas基本操作

一.查看数据 1.查看DataFrame前xx行或后xx行a=DataFrame(data);a.head(6)表示显示前6行数据,若head()中不带参数则会显示全部数据.a.tail(6)表示显示后6行数据,若tail()中不带参数则也会显示全部数据. 2.查看DataFrame的index,columns以及valuesa.index ; a.columns ; a.values 即可 3.describe()函数对于数据的快速统计汇总a.describe()对每一列数据进行统计,包括计数

pandas基础学习一

生成对象 用值列表生成 Series 时,Pandas 默认自动生成整数索引: In [3]: s = pd.Series([1, 3, 5, np.nan, 6, 8]) In [4]: s Out[4]: 0 1.0 1 3.0 2 5.0 3 NaN 4 6.0 5 8.0 dtype: float64 用含日期时间索引与标签的 NumPy 数组生成 DataFrame: In [5]: dates = pd.date_range('20130101', periods=6) In [6]

pandas入门

[原]十分钟搞定pandas 本文是对pandas官方网站上<10 Minutes to pandas>的一个简单的翻译,原文在这里.这篇文章是对pandas的一个简单的介绍,详细的介绍请参考:Cookbook .习惯上,我们会按下面格式引入所需要的包: 一.            创建对象 可以通过 Data Structure Intro Setion 来查看有关该节内容的详细信息. 1.可以通过传递一个list对象来创建一个Series,pandas会默认创建整型索引: 2.通过传递一个

【Python语言】十分钟搞定pandas

本文是对pandas官方网站上<10 Minutes to pandas>的一个简单的翻译,原文在这里.这篇文章是对pandas的一个简单的介绍,详细的介绍请参考:Cookbook .习惯上,我们会按下面格式引入所需要的包: 一.            创建对象 可以通过 Data Structure Intro Setion 来查看有关该节内容的详细信息. 1.可以通过传递一个list对象来创建一个Series,pandas会默认创建整型索引: 2.通过传递一个numpy array,时间索

pandas总结

### 一.创建对象  # 1.可以通过传递一个list对象来创建一个Series,pandas会默认创建整型索引: # s=pd.Series([1,3,5,np.nan,6,8]) # print(s) # # 2.通过传递一个numpy array,时间索引以及列标签来创建一个DataFrame: # dates=pd.date_range('20130101',periods=6) # print(dates) # df=pd.DataFrame(np.random.randn(6,4)

Python大数据处理模块Pandas

Python大数据处理模块Pandas [这篇转载自CSDNchengxuyuanyonghu的博客:http://blog.csdn.net/chengxuyuanyonghu/article/details/54956207] 目录 读取数据 索引 选择数据 简单运算 import pandas as pd read_csv to_csv 数据框操作 一            创建对象 二            查看数据 三            选择 四            缺失值处理

10 Minutes to pandas中文版

本文是对pandas官方网站上<10 Minutes to pandas>的一个简单的翻译,原文在这里.这篇文章是对pandas的一个简单的介绍,详细的介绍请参考:Cookbook .习惯上,我们会按下面格式引入所需要的包: http://www.cnblogs.com/chaosimple/p/4153083.html 一.            创建对象 可以通过 Data Structure Intro Setion 来查看有关该节内容的详细信息. 1.可以通过传递一个list对象来创建