创建时间序列

这里讲的时间序列,是时间序列数据的索引列。本节主要介绍怎么创建这个索引列。创建时间序列,可以直接创建,也可以以增量方式创建,或通过整体偏移进行创建。构成时间序列的数据,可以是时间点、时间段或时间差。[大谦MATLAB,dqmatlab点com]

时间表(时间序列数据)概述

在讲时间序列的创建之前,首先了解一下什么是时间序列数据。下面给出一个典型的时间序列数据。

测量值

时间

2022-03-18 00:00:00 5

2022-03-18 01:00:00 9

2022-03-18 02:00:00 6

2022-03-18 03:00:00 9

2022-03-18 04:00:00 8

… …

2022-03-21 23:00:00 1

2022-03-22 00:00:00 5

2022-03-22 01:00:00 10

2022-03-22 02:00:00 6

2022-03-22 03:00:00 9

上面的数据每隔1小时记录1个测量值,用时间列作为索引列,测量值列作为值,得到一个时间表或者说时间序列数据。当然,还可以有更多列。相对于MATLAB中的表,或Python中的Series或DataFrame,它的特殊之处在于索引列是日期时间数据。

MATLAB中,因为时间表是特殊的表,所以操作表的函数和方法时间表也基本上是有的。同样,Python中时间序列数据是特殊的Series或DataFrame,所以,操作Series或DataFrame的函数和方法对于时间序列数据也是适用的。

工作表或时间序列数据中的索引列,本书称为时间序列。本节接下来重点介绍怎么创建时间序列。

直接创建时间序列

可以直接以数组的形式给出各个时间,并用MATLAB和Python提供的函数创建时间序列。这种方法适用于数据量小,并且日期时间数据没有什么规律的情况。

【MATLAB】

MATLAB中,使用datetime函数可以直接将表示日期时间的字符串数组转换为日期时间类型的数组,即时间序列。在命令窗口键入:

code.matlab
>> ds=["2023-12-18 08:03:05"; "2023-12-18 10:03:17"; "2023-12-18 12:03:13"];
>> T=datetime(ds);
T=
  3×1 datetime 数组
   2023-12-18 08:03:05
   2023-12-18 10:03:17
   2023-12-18 12:03:13

【Python】

Python中使用pandas包的to_datetime函数将表示日期时间的字符串数组转换为时间序列。在Python IDLE Shell窗口键入:

code.python
>>> import pandas as pd
>>> days=['2020-9-1','2020-9-5','2020-10-1']
>>> days=pd.to_datetime(days)
>>> days
DatetimeIndex(['2020-09-01', '2020-09-05', '2020-10-01'], dtype='datetime64[ns]', freq=None)

也可以直接用DatetimeIndex函数进行创建。

code.python
>>> pd.DatetimeIndex(['2020-9-1','2020-9-5','2020-10-1'])
DatetimeIndex(['2020-09-01', '2020-09-05', '2020-10-01'], dtype='datetime64[ns]', freq=None)

用增量法创建时间序列

MATLAB和Python创建数组时,都有一种叫做增量法的创建方法。指定起始值、增量和叠加次数,通过不断叠加增量生成序列;或者指定起始值、终止值和增量生成序列。使用增量法,同样可以创建时间序列。

【MATLAB】

在MATLAB命令窗口键入:

code.matlab
>> T=datetime(2023,6,1:4);
>> T
T=
  1×4 datetime 数组
   2023-06-01   2023-06-02   2023-06-03   2023-06-04

生成了1号到4号4个日期组成的时间序列。也可以将冒号用于表示年份和月份的数字。还可以设置增量,默认时增量为1,可省略不写,如上面代码中所示。

code.matlab
>> T=datetime(2023,6,1:2:10);
>> T
T=
  1×5 datetime 数组
   2023-06-01   2023-06-03   2023-06-05   2023-06-07   2023-06-09

datetime函数中指定日期增量,即步长的值为2,所以生成的时间序列中相邻两个日期相差2天。

【Python】

Python中用pandas包的date_range函数可以增量式生成时间点表示的时间序列。该函数可以有两种用法。

一种是指定起始日期、终止日期和增量。下面代码指定起始日期为2020年10月12日,终止日期为2020年11月12日,增量为2天。

code.python
>>> pd.date_range(start='20201012',end='20201112',freq='2D')
DatetimeIndex(['2020-10-12', '2020-10-14', '2020-10-16', '2020-10-18',
               '2020-10-20', '2020-10-22', '2020-10-24', '2020-10-26',
               '2020-10-28', '2020-10-30', '2020-11-01', '2020-11-03',
               '2020-11-05', '2020-11-07', '2020-11-09', '2020-11-11'],
              dtype='datetime64[ns]', freq='2D')

另一种是指定起始日期、增量和时间点个数。下面代码指定起始日期为2020年10月12日,增量为2天,递增10次。

code.python
>>> pd.date_range(start='20201012',periods=10,freq='2D')
DatetimeIndex(['2020-10-12', '2020-10-14', '2020-10-16', '2020-10-18',
               '2020-10-20', '2020-10-22', '2020-10-24', '2020-10-26',
               '2020-10-28', '2020-10-30'],
              dtype='datetime64[ns]', freq='2D')

两种方法都生成了时间序列,它们都是DatetimeIndex对象。

通过偏移已有时间序列创建新时间序列

可以利用已有时间序列,通过给序列里的每个日期时间增加一个时间差得到新的日期时间,并最终得到一个新的时间序列。

【MATLAB】

MATLAB中可以直接给时间点数组加上相同大小的时间差数组得到新时间序列。在MATLAB命令窗口键入:

code.matlab
>> dt=[datetime('2023-10-10'),datetime('2023-10-11'),datetime('2023-10-12')];
>> ds=[days(1),days(5),days(10)];
>> dts=dt+ds
dts=
  1×3 datetime 数组
   2023-10-11   2023-10-16   2023-10-22

【Python】

Python中使用pandas包的DateOffset函数,通过对时间点进行偏移得到新的时间序列。

code.python
>>> dt=pd.Timestamp('2023-10-10')
>>> (dt+pd.DateOffset(days=5),dt+pd.DateOffset(days=10),dt+pd.DateOffset(days=15))
(Timestamp('2023-10-15 00:00:00'), Timestamp('2023-10-20 00:00:00'), Timestamp('2023-10-25 00:00:00'))

也可以构造时间点数组和时间差数组然后对应元素相加。

code.python
>>> dt=[pd.Timestamp('2023-10-10'),pd.Timestamp('2023-10-12'),pd.Timestamp('2023-10-15')]
>>> do=[pd.DateOffset(days=5),pd.DateOffset(days=10),pd.DateOffset(days=3)]
>>> result=list(map(lambda x, y: x + y, dt,do))
>>> result
[Timestamp('2023-10-15 00:00:00'), Timestamp('2023-10-22 00:00:00'), Timestamp('2023-10-18 00:00:00')]

用时间段创建时间序列

时间段数据也可以用于创建时间序列,并用于时间表或时间序列数据的索引列。关于时间段的概念,它与时间点和时间差的区别,请参见第6章。

【MATLAB】

MATLAB没有提供创建时间段的函数。可以使用结构或类进行构造。描述时间段需要有时间段的日期时间起点、终点、时长增量和递增次数等字段或属性。

【Python】

Python中可以用pandas包中的PeriodIndex函数直接创建时间段时间序列,例如:

code.python
>>> years=['2020','2021','2022']
>>> px=pd.PeriodIndex(years,freq='Y')
>>> px
PeriodIndex(['2020', '2021', '2022'], dtype='period[A-DEC]', freq='A-DEC')

也可以用period_range函数增量式创建时间段时间序列。与date_range函数的用法类似,period_range函数也有两种用法。

一种是指定起始日期、终止日期和增量。

code.python
>>> pd.period_range(start='20201012',end='20201016',freq='D')
PeriodIndex(['2020-10-12', '2020-10-13', '2020-10-14', '2020-10-15',
             '2020-10-16'],
            dtype='period[D]', freq='D')

另一种是指定起始日期、增量和时间段个数。

code.python
>>> pd.period_range(start='20201012',periods=5,freq='10D')
PeriodIndex(['2020-10-12', '2020-10-22', '2020-11-01', '2020-11-11',
             '2020-11-21'],
            dtype='period[10D]', freq='10D')

用时间差创建时间序列

时间差数据也可以用于创建时间序列,并用于时间表或时间序列数据的索引列。关于时间差的概念,它与时间点和时间段的区别,请参见第6章。

【MATLAB】

MATLAB中可以用duration函数创建时间差时间序列。在MATLAB命令窗口输入:

code.matlab
>> D=duration(6,10:15,5)
D =
  1x6 duration 数组
  06:10:05		06:11:05		06:12:05		06:13:05		06:14:05		06:15:05

注意,上面D数组中的各元素表示的不是时间点,比如06:10:05表示的不是6点10分5秒,而是表示6小时10分钟零5秒时间长度。

另外,MATLAB还提供了一系列生成以年、月、日、小时、分钟和秒等为单位的时长的函数。比如,下面用years函数创建N年表示的时间差。

code.matlab
>> Y=years(1:3)
Y=
  1×3 duration 数组
   1年   2年   3年

【Python】

Python中可以用pandas包中的TimedeltaIndex函数直接创建时间段时间序列,例如:

code.python
>>> days=[1,2,3]
>>> px=pd.TimedeltaIndex(days,unit='D')
>>> px
TimedeltaIndex(['1 days', '2 days', '3 days'], dtype='timedelta64[ns]', freq=None)

也可以用timedelta_range函数增量式创建时间段时间序列。与date_range函数的用法类似,timedelta_range函数也有两种用法。

一种是指定起始日期、终止日期和增量。

code.python
>>> pd.timedelta_range(start='1 days',end='3 days',freq='8H')
TimedeltaIndex(['1 days 00:00:00', '1 days 08:00:00', '1 days 16:00:00',
                '2 days 00:00:00', '2 days 08:00:00', '2 days 16:00:00',
                '3 days 00:00:00'],
               dtype='timedelta64[ns]', freq='8H')

另一种是指定起始日期、增量和时间段个数。

code.python
>>> pd.timedelta_range(start='1 days',periods=3)
TimedeltaIndex(['1 days', '2 days', '3 days'], dtype='timedelta64[ns]', freq='D')