摘要: 本 notebook 介绍了 sktime 的内存数据容器和数据集,以及相关的内存格式验证、转换和数据集加载等功能。
设置说明: 在 binder 上,此 notebook 应可直接运行。
为了按预期运行此 notebook,请确保您的 Python 环境中安装了 sktime 及其基本依赖项。
要运行 sktime 的本地开发版本,请取消注释并运行以下代码,或 pip install -e
sktime main
分支的本地克隆。
[1]:
# from os import sys
# sys.path.append("..")
内存数据表示和数据加载#
sktime 为许多时间序列相关的学习任务提供了模块。
这些模块使用 sktime 特定的内存(即 Python 工作空间)表示来处理时间序列及相关对象,最重要的是单个时间序列和时间序列面板。 sktime 的内存表示依赖于 pandas
和 numpy
,并对 pandas
和 numpy
对象附加了一些约定。
sktime 的用户应了解这些表示形式,因为将数据呈现为 sktime 兼容的表示形式通常是使用任何 sktime 模块的第一步。
本 notebook 介绍了 sktime 中使用的数据类型、相关的转换器和有效性检查器等功能,以及常见的数据加载和转换工作流程。
第 1 节 介绍了 sktime 中使用的内存数据容器格式,并提供示例。
第 2 节 介绍了内存数据容器的有效性检查器和转换功能。
第 3 节 介绍了加载预定义基准数据集的常见工作流程。
第 4 节 展示了从表格 csv
格式加载数据的常见工作流程。
第 1 节:内存数据容器#
本节提供了 sktime 中用于时间序列及相关对象的数据容器参考。
概念上,sktime 区分
数据容器的 数据科学抽象数据类型(简称:scitype),由所表示数据的关系和统计特性以及对其进行的常见操作定义——例如,抽象的“时间序列”或抽象的“时间序列面板”,而不指定具体的 Python 机器实现
数据容器的 机器实现类型(简称:mtype),它为已定义的 scitype 指定 Python 类型以及 Python 内存对象的结构和值约定。例如,在 sktime 中,一个具体的(数学)时间序列由一个具体的
pandas.DataFrame
表示,该pandas.DataFrame
必须遵守某些约定。形式上,这些约定构成一个特定的 mtype,即表示(抽象的)“时间序列”scitype 的一种方式。
在 sktime 中,同一个 scitype 可以由多个 mtype 实现。例如,sktime 允许用户将时间序列指定为 pandas.DataFrame
、pandas.Series
或 numpy.ndarray
。这些是不同的 mtype,它们是同一个 scitype“时间序列”的可接受表示。此外,并非所有 mtype 都包含同样丰富的元数据——例如,pandas.DataFrame
可以存储列名,而 numpy.ndarray
则无法做到。
在 sktime 中,scitype 和 mtype 使用字符串编码,以便于引用。
本节介绍以下 scitype 的 mtype
"Series"
,sktime 中表示任何类型时间序列的 scitype"Panel"
,sktime 中表示任何类型时间序列面板的 scitype"Hierarchical"
,sktime 中表示分层时间序列的 scitype
第 1.1 节:时间序列 - "Series"
scitype#
sktime 中时间序列的主要表示形式是
"pd.DataFrame"
- 一种单变量或多变量pandas.DataFrame
,行表示时间点,列表示变量"pd.Series"
- 一种(单变量)pandas.Series
,其条目对应不同的时间点"np.ndarray"
- 一种 2Dnumpy.ndarray
,行表示时间点,列表示变量
pandas
对象必须具有以下 pandas
索引类型之一:Int64Index
、RangeIndex
、DatetimeIndex
、PeriodIndex
;如果是 DatetimeIndex
,必须设置 freq
属性。
numpy.ndarray
2D 数组的行被解释为具有 RangeIndex
,并且通常等同于使用 pandas.DataFrame
构造函数进行默认强制转换后获得的 pandas.DataFrame
。
[2]:
# import to retrieve examples
from sktime.datatypes import get_examples
第 1.1.1 节:时间序列 - "pd.DataFrame"
mtype#
在 "pd.DataFrame"
mtype 中,时间序列由以下内存容器 obj: pandas.DataFrame
表示。
结构约定:
obj.index
必须是单调的,并且是Int64Index
、RangeIndex
、DatetimeIndex
、PeriodIndex
之一。变量:
obj
的列对应不同的变量变量名:列名
obj.columns
时间点:
obj
的行对应不同的、离散的时间点时间索引:
obj.index
被解释为时间索引。能力:可以表示多变量时间序列;可以表示不等间隔时间序列
"pd.DataFrame"
表示形式中的单变量时间序列示例。单个变量名为 "a"
,在四个时间点 0、1、2、3 进行观测。
[3]:
get_examples(mtype="pd.DataFrame", as_scitype="Series")[0]
[3]:
a | |
---|---|
0 | 1.0 |
1 | 4.0 |
2 | 0.5 |
3 | -3.0 |
"pd.DataFrame"
表示形式中的双变量时间序列示例。此时间序列有两个变量,命名为 "a"
和 "b"
。两者都在相同四个时间点 0、1、2、3 进行观测。
[4]:
get_examples(mtype="pd.DataFrame", as_scitype="Series")[1]
[4]:
a | b | |
---|---|---|
0 | 1.0 | 3.000000 |
1 | 4.0 | 7.000000 |
2 | 0.5 | 2.000000 |
3 | -3.0 | -0.428571 |
第 1.1.2 节:时间序列 - "pd.Series"
mtype#
在 "pd.Series"
mtype 中,时间序列由以下内存容器 obj: pandas.Series
表示。
结构约定:
obj.index
必须是单调的,并且是Int64Index
、RangeIndex
、DatetimeIndex
、PeriodIndex
之一。变量:只有一个变量,对应
obj
的值。只能表示单变量时间序列。变量名:默认情况下没有列名。如果需要,可以将变量名作为
obj.name
提供。时间点:
obj
的条目对应不同的、离散的时间点时间索引:
obj.index
被解释为时间索引。能力:不能表示多变量时间序列;可以表示不等间隔时间序列
"pd.Series"
mtype 表示形式中的单变量时间序列示例。单个变量名为 "a"
,在四个时间点 0、1、2、3 进行观测。
[5]:
get_examples(mtype="pd.Series", as_scitype="Series")[0]
[5]:
0 1.0
1 4.0
2 0.5
3 -3.0
Name: a, dtype: float64
第 1.1.3 节:时间序列 - "np.ndarray"
mtype#
在 "np.ndarray"
mtype 中,时间序列由以下内存容器 obj: np.ndarray
表示。
结构约定:
obj
必须是 2D 的,即obj.shape
的长度必须为 2。对于单变量时间序列也是如此。变量:变量对应
obj
的列。变量名:
"np.ndarray"
mtype 不能表示变量名。时间点:
obj
的行对应不同的、离散的时间点。时间索引:时间索引是隐式的,并通过约定定义。第
i
行(整数i
)被解释为在时间点i
的观测值。能力:可以表示多变量时间序列;不能表示不等间隔时间序列
"np.ndarray"
mtype 表示形式中的单变量时间序列示例。有一个(未命名)变量,在四个时间点 0、1、2、3 进行观测。
[6]:
get_examples(mtype="np.ndarray", as_scitype="Series")[0]
[6]:
array([[ 1. ],
[ 4. ],
[ 0.5],
[-3. ]])
"np.ndarray"
mtype 表示形式中的双变量时间序列示例。有两个(未命名)变量,它们都在四个时间点 0、1、2、3 进行观测。
[7]:
get_examples(mtype="np.ndarray", as_scitype="Series")[1]
[7]:
array([[ 1. , 3. ],
[ 4. , 7. ],
[ 0.5 , 2. ],
[-3. , -0.42857143]])
第 1.2 节:时间序列面板 - "Panel"
scitype#
sktime 中时间序列面板的主要表示形式是
"pd-multiindex"
- 一种pandas.DataFrame
,行多重索引为(实例,时间),列为变量"numpy3D"
- 一种 3Dnp.ndarray
,轴 0 为实例,轴 1 为变量,轴 2 为时间点"df-list"
- 一个pandas.DataFrame
的list
,列表索引为实例,数据框行表示时间点,数据框列表示变量
这些表示形式在 sktime 中被认为是主要表示形式,并且是内部计算的核心。
sktime 中还有其他次要的时间序列面板表示形式
"nested_univ"
- 一种pandas.DataFrame
,单元格中包含pandas.Series
。数据框行表示实例,数据框列表示变量,序列轴表示时间点"numpyflat"
- 一种 2Dnp.ndarray
,行表示实例,列通过(变量,时间点)对索引。此格式只能被转换成,不能从其转换(因为变量和时间点数量可能模糊)。"pd-wide"
- 一种宽格式的pandas.DataFrame
:具有列多重索引(变量,时间点),行表示实例;对于单变量时间序列,“变量”索引可以省略"pd-long"
- 一种长格式的pandas.DataFrame
:具有列instances
、timepoints
、variable
、value
;value
中的条目由 (instances
,timepoints`,
variable`) 中的值元组索引。
次要表示形式目前尚未完全在代码中整合,下文不再进一步讨论。欢迎贡献。
第 1.2.1 节:时间序列面板 - "pd-multiindex"
mtype#
在 "pd-multiindex"
mtype 中,时间序列面板由以下内存容器 obj: pandas.DataFrame
表示。
结构约定:
obj.index
必须是类型为(Index, t)
的对多重索引,其中t
是Int64Index
、RangeIndex
、DatetimeIndex
、PeriodIndex
之一且单调。obj.index
必须有两个级别(可以命名或不命名)。实例索引:
obj.index
中对的第一个元素(第 0 级别值)被解释为实例索引,下文我们称之为“实例索引”。实例:具有相同“实例索引”索引值的行对应同一个实例;具有不同“实例索引”值的行对应不同的实例。
时间索引:
obj.index
中对的第二个元素(第 1 级别值)被解释为时间索引,下文我们称之为“时间索引”。时间点:
obj
中具有相同“时间索引”值的行对应同一个时间点;obj
中具有不同“时间索引”的行对应不同的时间点。变量:
obj
的列对应不同的变量变量名:列名
obj.columns
能力:可以表示多变量时间序列面板;可以表示不等间隔时间序列;可以表示不等支持长度的时间序列面板;不能表示具有不同变量集的时间序列面板。
"pd-multiindex"
mtype 表示形式中的多变量时间序列面板示例。面板包含三个多变量时间序列,实例索引为 0、1、2。所有时间序列都有两个变量,名称分别为 "var_0"
、"var_1"
。所有时间序列都在三个时间点 0、1、2 进行观测。
[8]:
get_examples(mtype="pd-multiindex", as_scitype="Panel")[0]
[8]:
var_0 | var_1 | ||
---|---|---|---|
实例 | 时间点 | ||
0 | 0 | 1 | 4 |
1 | 2 | 5 | |
2 | 3 | 6 | |
1 | 0 | 1 | 4 |
1 | 2 | 55 | |
2 | 3 | 6 | |
2 | 0 | 1 | 42 |
1 | 2 | 5 | |
2 | 3 | 6 |
第 1.2.2 节:时间序列面板 - "numpy3D"
mtype#
在 "numpy3D"
mtype 中,时间序列面板由以下内存容器 obj: np.ndarray
表示。
结构约定:
obj
必须是 3D 的,即obj.shape
的长度必须为 3。实例:实例对应
obj
的轴 0 元素。实例索引:实例索引是隐式的,并通过约定定义。轴 0 的第
i
个元素(整数i
)被解释为指示观测实例i
。变量:变量对应
obj
的轴 1 元素。变量名:
"numpy3D"
mtype 不能表示变量名。时间点:时间点对应
obj
的轴 2 元素。时间索引:时间索引是隐式的,并通过约定定义。轴 2 的第
i
个元素(整数i
)被解释为在时间点i
的观测值。能力:可以表示多变量时间序列面板;不能表示不等间隔时间序列;不能表示不等支持长度的时间序列面板;不能表示具有不同变量集的时间序列面板。
"numpy3D"
mtype 表示形式中的多变量时间序列面板示例。面板包含三个多变量时间序列,实例索引为 0、1、2。所有时间序列都有两个(未命名)变量。所有时间序列都在三个时间点 0、1、2 进行观测。
[9]:
get_examples(mtype="numpy3D", as_scitype="Panel")[0]
[9]:
array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 1, 2, 3],
[ 4, 55, 6]],
[[ 1, 2, 3],
[42, 5, 6]]])
第 1.2.3 节:时间序列面板 - "df-list"
mtype#
在 "df-list"
mtype 中,时间序列面板由以下内存容器 obj: List[pandas.DataFrame]
表示。
结构约定:
obj
必须是pandas.DataFrames
的列表。obj
的单个列表元素必须遵循"Series"
scitype 的"pd.DataFrame"
mtype 约定。实例:实例对应
obj
的不同列表元素。实例索引:实例的实例索引是其在
obj
中所在的列表索引。也就是说,obj[i]
中的数据对应于索引为i
的实例的观测值。时间点:
obj[i]
的行对应不同的、离散的时间点,即实例i
被观测的时间点。时间索引:
obj[i].index
被解释为实例i
的时间索引。变量:
obj[i]
的列对应实例i
的不同可用变量。变量名:列名
obj[i].columns
是实例i
的可用变量名称。能力:可以表示多变量时间序列面板;可以表示不等间隔时间序列;可以表示不等支持长度的时间序列面板;可以表示具有不同变量集的时间序列面板。
"df-list"
mtype 表示形式中的多变量时间序列面板示例。面板包含三个多变量时间序列,实例索引为 0、1、2。所有时间序列都有两个变量,名称分别为 "var_0"
、"var_1"
。所有时间序列都在三个时间点 0、1、2 进行观测。
[10]:
get_examples(mtype="df-list", as_scitype="Panel")[0]
[10]:
[ var_0 var_1
0 1 4
1 2 5
2 3 6,
var_0 var_1
0 1 4
1 2 55
2 3 6,
var_0 var_1
0 1 42
1 2 5
2 3 6]
第 1.3 节:分层时间序列 - "Hierarchical"
scitype#
sktime 目前只有一种分层时间序列表示形式
"pd_multiindex_hier"
- 一种pandas.DataFrame
,具有行多重索引,最后一级解释为时间,其他级别解释为层次结构,列为变量
分层时间序列 - "pd_multiindex_hier"
mtype#
结构约定:
obj.index
必须是 3 级或更多级别的多重索引,类型为(Index, ..., Index, t)
,其中t
是Int64Index
、RangeIndex
、DatetimeIndex
、PeriodIndex
之一且单调。我们将最后一个索引称为“类时间”索引。层次级别:具有相同非类时间索引值的行对应同一层次单元;具有不同非类时间索引组合的行对应不同层次单元。
层次结构:
obj.index
中的非类时间索引被解释为标识层次结构的索引。时间索引:
obj.index
中元组的最后一个元素被解释为时间索引。时间点:
obj
中具有相同"timepoints"
索引的行对应同一个时间点;obj
中具有不同"timepoints"
索引的行对应不同的时间点。变量:
obj
的列对应不同的变量变量名:列名
obj.columns
能力:可以表示分层时间序列;可以表示不等间隔时间序列;可以表示不等支持长度的分层时间序列;不能表示具有不同变量集的分层时间序列。
[11]:
get_examples(mtype="pd_multiindex_hier", as_scitype="Hierarchical")[0]
[11]:
var_0 | var_1 | |||
---|---|---|---|---|
foo | bar | 时间点 | ||
a | 0 | 0 | 1 | 4 |
1 | 2 | 5 | ||
2 | 3 | 6 | ||
1 | 0 | 1 | 4 | |
1 | 2 | 55 | ||
2 | 3 | 6 | ||
2 | 0 | 1 | 42 | |
1 | 2 | 5 | ||
2 | 3 | 6 | ||
b | 0 | 0 | 1 | 4 |
1 | 2 | 5 | ||
2 | 3 | 6 | ||
1 | 0 | 1 | 4 | |
1 | 2 | 55 | ||
2 | 3 | 6 | ||
2 | 0 | 1 | 42 | |
1 | 2 | 5 | ||
2 | 3 | 6 |
第 2 节:有效性检查和 mtype 转换#
sktime 的 datatypes
模块为用户提供了通用功能,用于
检查内存容器是否符合 mtype 约定,并提供有用的错误消息,帮助将数据转换为正确格式
在给定 scitype 下,将不同的 mtype 相互转换
本节将介绍这些功能和预期用法工作流程。
第 2.1 节:准备数据,检查内存容器的有效性#
sktime 的 datatypes
模块提供了方便的功能,用户可以使用 check_is_mtype
和 check_raise
函数检查其内存数据容器的有效性。这两个函数都提供了通用的有效性检查功能,check_is_mtype
作为返回值返回元数据和潜在问题,而 check_raise
在容器不符合给定的 mtype
时直接产生有用的错误消息。
确保给定数据容器符合 sktime mtype
规范的推荐 notebook 工作流程如下
将数据加载到内存数据容器中
确定
scitype
,例如,这是时间序列(Series
)还是时间序列面板(Panel
)选择目标
mtype
(列表参见第 1 节),如果数据尚不符合要求,尝试手动重新格式化数据以符合mtype
规范对数据容器运行
check_raise
,以检查其是否符合mtype
和scitype
如果引发错误,重复步骤 3 和 4,直到不再引发错误
第 2.1.1 节:有效性检查,示例 1(简单错误)#
假设我们有以下 numpy.ndarray
表示单变量时间序列
[12]:
import numpy as np
y = np.array([1, 6, 3, 7, 2])
检查与 sktime 的兼容性
(说明:取消注释并运行代码以查看有用的错误消息)
[13]:
from sktime.datatypes import check_raise
# check_raise(y, mtype="np.ndarray")
这告诉我们,如果使用 np.ndarray
mtype,sktime 对时间序列使用 2D numpy 数组。虽然大多数方法都提供了自动执行此强制转换的便捷功能,但“正确”格式应为 2D,如下所示
[14]:
check_raise(y.reshape(-1, 1), mtype="np.ndarray")
[14]:
True
为了在自己的代码或附加元数据中使用,可以使用 check_is_mtype
函数获取错误消息
[15]:
from sktime.datatypes import check_is_mtype
check_is_mtype(y, mtype="np.ndarray", return_metadata=True)
[15]:
(True,
None,
{'is_empty': False,
'is_univariate': True,
'n_features': 1,
'feature_names': [0],
'dtypekind_dfip': [<DtypeKind.FLOAT: 2>],
'feature_kind': [<DtypeKind.FLOAT: 2>],
'is_equally_spaced': True,
'has_nans': False,
'mtype': 'np.ndarray',
'scitype': 'Series'})
如果参数通过有效性检查,则会产生元数据
[16]:
check_is_mtype(y.reshape(-1, 1), mtype="np.ndarray", return_metadata=True)
[16]:
(True,
None,
{'is_empty': False,
'is_univariate': True,
'n_features': 1,
'feature_names': [0],
'dtypekind_dfip': [<DtypeKind.FLOAT: 2>],
'feature_kind': [<DtypeKind.FLOAT: 2>],
'is_equally_spaced': True,
'has_nans': False,
'mtype': 'np.ndarray',
'scitype': 'Series'})
注意:如果 mtype 的名称含糊不清,可能指代多个 scitype,则必须提供附加参数 scitype
。对于任何常见的内存容器,都不应出现这种情况,我们在此提及是为了完整性。
[17]:
check_is_mtype(y, mtype="np.ndarray", scitype="Series")
[17]:
True
第 2.1.2 节:有效性检查,示例 2(不明显错误)#
假设我们将数据转换成了多重索引面板,即,我们想要一个 mtype 为 pd-multiindex
的 Panel
。
[18]:
import pandas as pd
cols = ["instances", "time points"] + [f"var_{i}" for i in range(2)]
X = pd.concat(
[
pd.DataFrame([[0, 0, 1, 4], [0, 1, 2, 5], [0, 2, 3, 6]], columns=cols),
pd.DataFrame([[1, 0, 1, 4], [1, 1, 2, 55], [1, 2, 3, 6]], columns=cols),
pd.DataFrame([[2, 0, 1, 42], [2, 1, 2, 5], [2, 2, 3, 6]], columns=cols),
]
).set_index(["instances", "time points"])
X
是否满足 pd-multiindex
规范并不明显,所以我们来检查一下
(说明:取消注释并运行代码以查看有用的错误消息)
[19]:
from sktime.datatypes import check_raise
# check_raise(X, mtype="pd-multiindex")
有用的错误消息突出了多重索引列中的一个拼写错误,所以我们这样做
[20]:
X.index.names = ["instances", "timepoints"]
现在有效性检查通过了
[21]:
check_raise(X, mtype="pd-multiindex")
[21]:
True
第 2.1.3 节:推断 mtype#
sktime 还提供了推断内存数据容器 mtype 的功能,这在确定容器符合要求但忘记了确切字符串,或者想要知道内存容器是否已处于某种受支持的、符合要求的格式时非常有用。为此,只需指定 scitype
[22]:
from sktime.datatypes import mtype
mtype(X, as_scitype="Panel")
[22]:
'pd-multiindex'
第 2.2 节:mtype 之间的转换#
sktime 的 datatypes
模块还提供了统一的 mtype 转换功能。这对用户和方法开发者都很有用。
convert
函数需要指定要从哪种 mtype 转换以及要转换成哪种 mtype。convert_to
函数只需要指定要转换成的 mtype,如果输入可以推断,它会自动推断输入的 mtype。如果输入可以有多种 mtype,应使用 convert_to
。
第 2.2.1 节:简单转换#
示例:将 numpy3D
时间序列面板转换为 pd-multiindex
mtype
[23]:
from sktime.datatypes import get_examples
X = get_examples(mtype="numpy3D", as_scitype="Panel")[0]
X
[23]:
array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 1, 2, 3],
[ 4, 55, 6]],
[[ 1, 2, 3],
[42, 5, 6]]])
[24]:
from sktime.datatypes import convert
convert(X, from_type="numpy3D", to_type="pd-multiindex")
[24]:
var_0 | var_1 | ||
---|---|---|---|
实例 | 时间点 | ||
0 | 0 | 1 | 4 |
1 | 2 | 5 | |
2 | 3 | 6 | |
1 | 0 | 1 | 4 |
1 | 2 | 55 | |
2 | 3 | 6 | |
2 | 0 | 1 | 42 |
1 | 2 | 5 | |
2 | 3 | 6 |
[25]:
from sktime.datatypes import convert_to
convert_to(X, to_type="pd-multiindex")
[25]:
var_0 | var_1 | ||
---|---|---|---|
实例 | 时间点 | ||
0 | 0 | 1 | 4 |
1 | 2 | 5 | |
2 | 3 | 6 | |
1 | 0 | 1 | 4 |
1 | 2 | 55 | |
2 | 3 | 6 | |
2 | 0 | 1 | 42 |
1 | 2 | 5 | |
2 | 3 | 6 |
第 2.2.2 节:高级转换功能#
convert_to
还允许指定多个输出类型。to_type
参数可以是 mtype 列表。在这种情况下,如果输入的 mtype 在列表中,则输入将不作更改地传递;如果输入的 mtype 不在列表中,则将其转换为列表中的第一个 mtype。
示例:将时间序列面板转换为 "pd-multiindex"
或 "numpy3D"
。如果输入是 "numpy3D"
,则保持不变。如果输入是 "df-list"
,则转换为 "pd-multiindex"
。
[26]:
from sktime.datatypes import get_examples
X = get_examples(mtype="numpy3D", as_scitype="Panel")[0]
X
[26]:
array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 1, 2, 3],
[ 4, 55, 6]],
[[ 1, 2, 3],
[42, 5, 6]]])
[27]:
from sktime.datatypes import convert_to
convert_to(X, to_type=["pd-multiindex", "numpy3D"])
[27]:
array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 1, 2, 3],
[ 4, 55, 6]],
[[ 1, 2, 3],
[42, 5, 6]]])
[28]:
X = get_examples(mtype="df-list", as_scitype="Panel")[0]
X
[28]:
[ var_0 var_1
0 1 4
1 2 5
2 3 6,
var_0 var_1
0 1 4
1 2 55
2 3 6,
var_0 var_1
0 1 42
1 2 5
2 3 6]
[29]:
convert_to(X, to_type=["pd-multiindex", "numpy3D"])
[29]:
var_0 | var_1 | ||
---|---|---|---|
实例 | 时间点 | ||
0 | 0 | 1 | 4 |
1 | 2 | 5 | |
2 | 3 | 6 | |
1 | 0 | 1 | 4 |
1 | 2 | 55 | |
2 | 3 | 6 | |
2 | 0 | 1 | 42 |
1 | 2 | 5 | |
2 | 3 | 6 |
第 2.2.3 节:检查已实现的转换#
目前,转换功能正在开发中,并非所有可能的转换都已可用——欢迎贡献。要查看某个 scitype 当前已实现哪些转换,请使用 datatypes._convert
模块中的开发者方法 _conversions_defined
。这将生成一个表格,如果已实现从行中的 mtype 到列中的 mtype 的转换,则显示“1”。
[30]:
from sktime.datatypes._convert import _conversions_defined
_conversions_defined(scitype="Panel")
[30]:
df-list | gluonts_ListDataset_panel | gluonts_PandasDataset_panel | nested_univ | numpy3D | numpyflat | pd-long | pd-multiindex | pd-wide | |
---|---|---|---|---|---|---|---|---|---|
df-list | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
gluonts_ListDataset_panel | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
gluonts_PandasDataset_panel | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
nested_univ | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
numpy3D | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
numpyflat | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
pd-long | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
pd-multiindex | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
pd-wide | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 |
第 3 节:加载预定义数据集#
sktime 的 datasets
模块允许加载数据集用于测试和基准测试。这包括
直接随 sktime 提供的示例数据集
从常见仓库下载数据集的下载器
以这种方式检索的所有数据都采用 sktime 兼容的内存和/或文件格式。
目前尚未实现对可用数据集的系统性标记和注册表检索功能——非常欢迎对此做出贡献。
第 3.1 节:预测数据集#
sktime 的 datasets
模块目前允许加载以下预测示例数据集
数据集名称 |
加载函数 |
属性 |
---|---|---|
Box/Jenkins 航班数据 |
|
单变量 |
Lynx 销售数据 |
|
单变量 |
洗发水销售数据 |
|
单变量 |
药物福利计划数据 |
|
单变量 |
Longley 美国宏观经济数据 |
|
多变量 |
MTS 消费/收入数据 |
|
多变量 |
sktime 目前没有连接到预测数据仓库的连接器——非常感谢贡献。
预测数据集都是 Series
scitype,可以是单变量或多变量。
单变量数据的加载器没有参数,并且始终返回 "pd.Series"
mtype 的数据
[31]:
from sktime.datasets import load_airline
load_airline()
[31]:
Period
1949-01 112.0
1949-02 118.0
1949-03 132.0
1949-04 129.0
1949-05 121.0
...
1960-08 606.0
1960-09 508.0
1960-10 461.0
1960-11 390.0
1960-12 432.0
Freq: M, Name: Number of airline passengers, Length: 144, dtype: float64
多变量数据的加载器可以通过两种方式调用
不带参数,这种情况下返回
"pd.DataFrame"
mtype 的多变量时间序列
[32]:
from sktime.datasets import load_longley
load_longley()
[32]:
(Period
1947 60323.0
1948 61122.0
1949 60171.0
1950 61187.0
1951 63221.0
1952 63639.0
1953 64989.0
1954 63761.0
1955 66019.0
1956 67857.0
1957 68169.0
1958 66513.0
1959 68655.0
1960 69564.0
1961 69331.0
1962 70551.0
Freq: A-DEC, Name: TOTEMP, dtype: float64,
GNPDEFL GNP UNEMP ARMED POP
Period
1947 83.0 234289.0 2356.0 1590.0 107608.0
1948 88.5 259426.0 2325.0 1456.0 108632.0
1949 88.2 258054.0 3682.0 1616.0 109773.0
1950 89.5 284599.0 3351.0 1650.0 110929.0
1951 96.2 328975.0 2099.0 3099.0 112075.0
1952 98.1 346999.0 1932.0 3594.0 113270.0
1953 99.0 365385.0 1870.0 3547.0 115094.0
1954 100.0 363112.0 3578.0 3350.0 116219.0
1955 101.2 397469.0 2904.0 3048.0 117388.0
1956 104.6 419180.0 2822.0 2857.0 118734.0
1957 108.4 442769.0 2936.0 2798.0 120445.0
1958 110.8 444546.0 4681.0 2637.0 121950.0
1959 112.6 482704.0 3813.0 2552.0 123366.0
1960 114.2 502601.0 3931.0 2514.0 125368.0
1961 115.7 518173.0 4806.0 2572.0 127852.0
1962 116.9 554894.0 4007.0 2827.0 130081.0)
带有参数
y_name
,该参数必须与某个列/变量名一致,在这种情况下返回一对时间序列y
和X
,其中y
是"pd.Series"
mtype,X
是"pd.DataFrame"
mtype——这对于包含外生变量的单变量预测很方便。
[33]:
y, X = load_longley(y_name="TOTEMP")
[34]:
y
[34]:
Period
1947 60323.0
1948 61122.0
1949 60171.0
1950 61187.0
1951 63221.0
1952 63639.0
1953 64989.0
1954 63761.0
1955 66019.0
1956 67857.0
1957 68169.0
1958 66513.0
1959 68655.0
1960 69564.0
1961 69331.0
1962 70551.0
Freq: A-DEC, Name: TOTEMP, dtype: float64
[35]:
X
[35]:
GNPDEFL | GNP | UNEMP | ARMED | POP | |
---|---|---|---|---|---|
周期 | |||||
1947 | 83.0 | 234289.0 | 2356.0 | 1590.0 | 107608.0 |
1948 | 88.5 | 259426.0 | 2325.0 | 1456.0 | 108632.0 |
1949 | 88.2 | 258054.0 | 3682.0 | 1616.0 | 109773.0 |
1950 | 89.5 | 284599.0 | 3351.0 | 1650.0 | 110929.0 |
1951 | 96.2 | 328975.0 | 2099.0 | 3099.0 | 112075.0 |
1952 | 98.1 | 346999.0 | 1932.0 | 3594.0 | 113270.0 |
1953 | 99.0 | 365385.0 | 1870.0 | 3547.0 | 115094.0 |
1954 | 100.0 | 363112.0 | 3578.0 | 3350.0 | 116219.0 |
1955 | 101.2 | 397469.0 | 2904.0 | 3048.0 | 117388.0 |
1956 | 104.6 | 419180.0 | 2822.0 | 2857.0 | 118734.0 |
1957 | 108.4 | 442769.0 | 2936.0 | 2798.0 | 120445.0 |
1958 | 110.8 | 444546.0 | 4681.0 | 2637.0 | 121950.0 |
1959 | 112.6 | 482704.0 | 3813.0 | 2552.0 | 123366.0 |
1960 | 114.2 | 502601.0 | 3931.0 | 2514.0 | 125368.0 |
1961 | 115.7 | 518173.0 | 4806.0 | 2572.0 | 127852.0 |
1962 | 116.9 | 554894.0 | 4007.0 | 2827.0 | 130081.0 |
第 3.2 节:时间序列分类数据集#
sktime 的 datasets
模块目前允许加载以下时间序列分类示例数据集
数据集名称 |
加载函数 |
属性 |
---|---|---|
电器功耗数据 |
|
单变量,等长/索引 |
箭头形状数据 |
|
单变量,等长/索引 |
Gunpoint 运动数据 |
|
单变量,等长/索引 |
意大利电力需求数据 |
|
单变量,等长/索引 |
日语元音数据 |
|
单变量,等长/索引 |
OSUleaf 叶形数据 |
|
单变量,等长/索引 |
基本运动数据 |
|
多变量,等长/索引 |
目前,sktime 中没有直接包含不等长或不等索引的时间序列分类示例数据。
sktime 还通过 load_UCR_UEA_dataset
函数提供了对 UCR/UEA 时间序列数据集存档的完整接口。UCR/UEA 存档也包含多变量或不等长/不等索引(任一组合)的时间序列分类数据集。
第 3.2.2 节:sktime 中的时间序列分类数据集#
时间序列分类数据集由 Panel
scitype 的时间序列面板以及分类标签组成,每个时间序列对应一个标签。
如果使用最小参数调用加载器,数据将以 "nested_univ"
mtype 返回,标签和待分类的时间序列都在同一个 pd.DataFrame
中。使用 return_X_y=True
参数,数据会分离返回特征 X
和标签 y
,其中 X
是 nested_univ
mtype 的 Panel
,y
是 sklearn
兼容的标签 numpy 向量。
[36]:
from sktime.datasets import load_arrow_head
X, y = load_arrow_head(return_X_y=True)
[37]:
X
[37]:
dim_0 | |
---|---|
0 | 0 -1.963009 1 -1.957825 2 -1.95614... |
1 | 0 -1.774571 1 -1.774036 2 -1.77658... |
2 | 0 -1.866021 1 -1.841991 2 -1.83502... |
3 | 0 -2.073758 1 -2.073301 2 -2.04460... |
4 | 0 -1.746255 1 -1.741263 2 -1.72274... |
... | ... |
206 | 0 -1.625142 1 -1.622988 2 -1.62606... |
207 | 0 -1.657757 1 -1.664673 2 -1.63264... |
208 | 0 -1.603279 1 -1.587365 2 -1.57740... |
209 | 0 -1.739020 1 -1.741534 2 -1.73286... |
210 | 0 -1.630727 1 -1.629918 2 -1.62055... |
211 行 × 1 列
[38]:
y
[38]:
array(['0', '1', '2', '0', '1', '2', '0', '1', '2', '0', '1', '2', '0',
'1', '2', '0', '1', '2', '0', '1', '2', '0', '1', '2', '0', '1',
'2', '0', '1', '2', '0', '1', '2', '0', '1', '2', '0', '0', '0',
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'0', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
'1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
'1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
'1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
'1', '1', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
'2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
'2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
'2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
'2', '2', '2'], dtype='<U1')
面板可以从 "nested_univ"
mtype 转换为其他 mtype 格式,使用 datatypes.convert
或 convert_to
(参见上文)
[39]:
from sktime.datatypes import convert_to
convert_to(X, to_type="pd-multiindex")
[39]:
dim_0 | ||
---|---|---|
0 | 0 | -1.963009 |
1 | -1.957825 | |
2 | -1.956145 | |
3 | -1.938289 | |
4 | -1.896657 | |
... | ... | ... |
210 | 246 | -1.513637 |
247 | -1.550431 | |
248 | -1.581576 | |
249 | -1.595273 | |
250 | -1.620783 |
52961 行 × 1 列
可以使用 split
参数调用数据集加载器,以获取可重现的训练集和测试集,用于跨研究进行比较。如果 split="train"
,则检索预定义的训练集;如果 split="test"
,则检索预定义的测试集。
[40]:
X_train, y_train = load_arrow_head(return_X_y=True, split="train")
X_test, y_test = load_arrow_head(return_X_y=True, split="test")
# this retrieves training and test X/y for reproducible use in studies
第 3.2.3 节:来自 UCR/UEA 时间序列分类仓库的时间序列分类数据集#
load_UCR_UEA_dataset
工具将从 UCR/UEA 时间序列分类仓库下载数据集,并以与 sktime 本地数据集加载器相同的语法将其作为内存数据集提供。
数据集通过唯一的字符串标识符进行索引,可以在 仓库本身 查看,或者通过 datasets.tsc_dataset_names
模块中的注册表按属性查看
[41]:
from sktime.datasets.tsc_dataset_names import univariate
导入的变量都是字符串列表,其中包含具有某些属性的数据集的唯一字符串标识符,如下所示
注册名称 |
单变量/多变量 |
等长/不等长 |
包含/不包含缺失值 |
---|---|---|---|
|
仅单变量 |
两者都包含 |
两者都包含 |
|
仅多变量 |
两者都包含 |
两者都包含 |
|
仅单变量 |
仅等长 |
两者都包含 |
|
仅单变量 |
仅不等长 |
两者都包含 |
|
仅单变量 |
两者都包含 |
仅包含缺失值 |
|
仅多变量 |
仅等长 |
两者都包含 |
|
仅多变量 |
仅不等长 |
两者都包含 |
老实说,使用这些列表进行查找和检索有点不方便——非常欢迎对 sktime 做出贡献,编写基于数据集能力或属性标签的查找函数,例如 all_estimators
或 all_tags
。
下面显示一个示例列表
[42]:
univariate
[42]:
['ACSF1',
'Adiac',
'AllGestureWiimoteX',
'AllGestureWiimoteY',
'AllGestureWiimoteZ',
'ArrowHead',
'AsphaltObstacles',
'Beef',
'BeetleFly',
'BirdChicken',
'BME',
'Car',
'CBF',
'Chinatown',
'ChlorineConcentration',
'CinCECGTorso',
'Coffee',
'Computers',
'CricketX',
'CricketY',
'CricketZ',
'Crop',
'DiatomSizeReduction',
'DistalPhalanxOutlineCorrect',
'DistalPhalanxOutlineAgeGroup',
'DistalPhalanxTW',
'DodgerLoopDay',
'DodgerLoopGame',
'DodgerLoopWeekend',
'Earthquakes',
'ECG200',
'ECG5000',
'ECGFiveDays',
'ElectricDevices',
'EOGHorizontalSignal',
'EOGVerticalSignal',
'EthanolLevel',
'FaceAll',
'FaceFour',
'FacesUCR',
'FiftyWords',
'Fish',
'FordA',
'FordB',
'FreezerRegularTrain',
'FreezerSmallTrain',
'Fungi',
'GestureMidAirD1',
'GestureMidAirD2',
'GestureMidAirD3',
'GesturePebbleZ1',
'GesturePebbleZ2',
'GunPoint',
'GunPointAgeSpan',
'GunPointMaleVersusFemale',
'GunPointOldVersusYoung',
'Ham',
'HandOutlines',
'Haptics',
'Herring',
'HouseTwenty',
'InlineSkate',
'InsectEPGRegularTrain',
'InsectEPGSmallTrain',
'InsectWingbeatSound',
'ItalyPowerDemand',
'LargeKitchenAppliances',
'Lightning2',
'Lightning7',
'Mallat',
'Meat',
'MedicalImages',
'MelbournePedestrian',
'MiddlePhalanxOutlineCorrect',
'MiddlePhalanxOutlineAgeGroup',
'MiddlePhalanxTW',
'MixedShapesRegularTrain',
'MixedShapesSmallTrain',
'MoteStrain',
'NonInvasiveFetalECGThorax1',
'NonInvasiveFetalECGThorax2',
'OliveOil',
'OSULeaf',
'PhalangesOutlinesCorrect',
'Phoneme',
'PickupGestureWiimoteZ',
'PigAirwayPressure',
'PigArtPressure',
'PigCVP',
'PLAID',
'Plane',
'PowerCons',
'ProximalPhalanxOutlineCorrect',
'ProximalPhalanxOutlineAgeGroup',
'ProximalPhalanxTW',
'RefrigerationDevices',
'Rock',
'ScreenType',
'SemgHandGenderCh2',
'SemgHandMovementCh2',
'SemgHandSubjectCh2',
'ShakeGestureWiimoteZ',
'ShapeletSim',
'ShapesAll',
'SmallKitchenAppliances',
'SmoothSubspace',
'SonyAIBORobotSurface1',
'SonyAIBORobotSurface2',
'StarLightCurves',
'Strawberry',
'SwedishLeaf',
'Symbols',
'SyntheticControl',
'ToeSegmentation1',
'ToeSegmentation2',
'Trace',
'TwoLeadECG',
'TwoPatterns',
'UMD',
'UWaveGestureLibraryAll',
'UWaveGestureLibraryX',
'UWaveGestureLibraryY',
'UWaveGestureLibraryZ',
'Wafer',
'Wine',
'WordSynonyms',
'Worms',
'WormsTwoClass']
加载函数 load_UCR_UEA_dataset
的行为与 sktime 数据加载器完全相同,但增加了一个参数 name
,该参数应设置为 UCR/UEA 数据集的唯一标识字符串之一,例如
[43]:
from sktime.datasets import load_UCR_UEA_dataset
X, y = load_UCR_UEA_dataset(name="ArrowHead", return_X_y=True)
这会将数据集下载到本地目录(默认情况下:如果是本地克隆,则下载到本地仓库的 datasets/data
目录中;如果是发布安装,则下载到本地 Python 环境文件夹中)。要更改该目录,请使用 load_UCR_UEA_dataset
函数的 extract_path
参数进行指定。
第 4 节:从 csv
文件加载数据#
本节展示了如何将一些常见的表格 csv
格式加载到 sktime 兼容的容器中。
我们将涵盖
将时间序列数据集转换为 sktime 兼容的容器
将面板数据集转换为 sktime 兼容的容器
我们假设 所有 csv 文件都具有某些表格格式。
这意味着 csv
文件包含时间索引列,或者面板数据的实例索引,或者采用宽格式表格。
注意:在每一步,我们都可以使用 check_is_mtype
来检查是否符合目标格式。读者可以这样做。
第 4.1 节:简单时间序列示例#
[44]:
import pandas as pd
df_series = pd.read_csv("../sktime/datasets/data/Airline/Airline.csv")
df_series.head()
[44]:
日期 | 乘客 | |
---|---|---|
0 | 1949-01 | 112 |
1 | 1949-02 | 118 |
2 | 1949-03 | 132 |
3 | 1949-04 | 129 |
4 | 1949-05 | 121 |
[45]:
df_series = df_series.set_index(
"Date"
).squeeze() # replace "Period" with the column name of the time index
df_series.index = pd.DatetimeIndex(df_series.index)
[46]:
mtype(df_series, as_scitype="Series")
[46]:
'pd.Series'
第 4.2 节:简单面板数据示例#
[47]:
# mimicking a scenario where we already have a csv file in the right format
from sktime.datasets import load_arrow_head
df_panel = load_arrow_head(split="TRAIN", return_type="pd-multiindex")[0].reset_index()
# imagine this is the result of df_panel = pd.read_csv
[48]:
df_panel.head()
[48]:
level_0 | level_1 | dim_0 | |
---|---|---|---|
0 | 0 | 0 | -1.963009 |
1 | 0 | 1 | -1.957825 |
2 | 0 | 2 | -1.956145 |
3 | 0 | 3 | -1.938289 |
4 | 0 | 4 | -1.896657 |
这类似于 pd-multiindex 格式,所以我们尝试将其转换为该格式。
我们需要改变的一点是将实例/时间设置为索引
[49]:
df_panel = df_panel.set_index(["level_0", "level_1"])
type(df_panel.index)
[49]:
pandas.core.indexes.multi.MultiIndex
sktime 现在将其识别为 pd-multiindex 格式
[50]:
mtype(df_panel, as_scitype="Panel")
# in general:
# replace "timepoints" with the time index column name
# replace "level_0" with the higher level column name of your file
[50]:
'pd-multiindex'
第 4.3 节:复杂面板数据示例#
现在我们尝试从一个格式有点挑战性的文件中加载面板数据
在下面的文件中
分隔符不是默认的逗号,而是制表符。为此,我们设置
sep=\t
文件中没有头部
没有实例索引,所以我们需要添加它
索引方式与 sktime 不同——第一列是变量索引,列是时间索引
这些或类似的挑战在面板数据的 csv
文件中很常见,因此我们将在下面展示如何解决它们。
建议将数据转换为纯粹基于 pandas
或 numpy
的格式。在下面的例子中,我们将把数据转换为 pd-multiindex
格式。
[51]:
# 1, 2 - dealing with the separator and header
import pandas as pd
df_panel = pd.read_csv(
"../sktime/datasets/data/ArrowHead/ArrowHead_TRAIN.tsv",
sep="\t",
header=None,
)
df_panel.head()
[51]:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ... | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | -1.963009 | -1.957825 | -1.956145 | -1.938289 | -1.896657 | -1.869857 | -1.838705 | -1.812289 | -1.736433 | ... | -1.583857 | -1.655329 | -1.719153 | -1.750881 | -1.796273 | -1.841345 | -1.884289 | -1.905393 | -1.923905 | -1.909153 |
1 | 1 | -1.774571 | -1.774036 | -1.776586 | -1.730749 | -1.696268 | -1.657377 | -1.636227 | -1.609807 | -1.543439 | ... | -1.471688 | -1.484666 | -1.539972 | -1.590150 | -1.635663 | -1.639989 | -1.678683 | -1.729227 | -1.775670 | -1.789324 |
2 | 2 | -1.866021 | -1.841991 | -1.835025 | -1.811902 | -1.764390 | -1.707687 | -1.648280 | -1.582643 | -1.531502 | ... | -1.584132 | -1.652337 | -1.684565 | -1.743972 | -1.799117 | -1.829069 | -1.875828 | -1.862512 | -1.863368 | -1.846493 |
3 | 0 | -2.073758 | -2.073301 | -2.044607 | -2.038346 | -1.959043 | -1.874494 | -1.805619 | -1.731043 | -1.712653 | ... | -1.678942 | -1.743732 | -1.819801 | -1.858136 | -1.886146 | -1.951247 | -2.012927 | -2.026963 | -2.073405 | -2.075292 |
4 | 1 | -1.746255 | -1.741263 | -1.722741 | -1.698640 | -1.677223 | -1.630356 | -1.579440 | -1.551225 | -1.473980 | ... | -1.547111 | -1.607101 | -1.635137 | -1.686346 | -1.691274 | -1.716886 | -1.740726 | -1.743442 | -1.762729 | -1.763428 |
5 行 × 252 列
[52]:
# 2 - adding an instance index manually
import numpy as np
df_panel["instance"] = np.repeat(range(len(df_panel) // 3), 3)
现在我们通过反透视将数据转换为长格式
[53]:
# 3 - add instance index
df_panel.columns = ["var"] + [f"value{i}" for i in range(251)] + ["instance"]
# 4 - move to long format
df_panel = pd.wide_to_long(df_panel, "value", i=["var", "instance"], j="time")
[54]:
df_panel.head()
[54]:
值 | |||
---|---|---|---|
变量 | 实例 | 时间 | |
0 | 0 | 0 | -1.963009 |
1 | -1.957825 | ||
2 | -1.956145 | ||
3 | -1.938289 | ||
4 | -1.896657 |
现在“变量”索引在行中,但它应该在列中
[55]:
# 3 - move variable index to columns
df_panel = df_panel.reset_index("var")
df_panel = df_panel.pivot(columns="var", values="value")
[56]:
df_panel.head()
[56]:
变量 | 0 | 1 | 2 | |
---|---|---|---|---|
实例 | 时间 | |||
0 | 0 | -1.963009 | -1.774571 | -1.866021 |
1 | -1.957825 | -1.774036 | -1.841991 | |
2 | -1.956145 | -1.776586 | -1.835025 | |
3 | -1.938289 | -1.730749 | -1.811902 | |
4 | -1.896657 | -1.696268 | -1.764390 |
这现在是 pd-multiindex 格式了
[57]:
mtype(df_panel, as_scitype="Panel")
[57]:
'pd-multiindex'
另一种方法是删除索引,然后在 numpy
中使用 reshape。
[57]: