在 Python 中获取时间序列数据集指南

来自真实世界场景的数据集对于构建和测试机器学习模型至关重要。您可能只是想获得一些数据来实验算法。您也可能想通过建立一个基准来评估您的模型,或者使用不同的数据集来确定其弱点。有时,您还可能想创建合成数据集,通过向数据中添加噪声、相关性或冗余信息,在受控条件下测试您的算法。

在本帖中,我们将说明如何使用 Python 从不同来源获取一些真实世界的时间序列数据。我们还将使用 Python 的库创建合成时间序列数据。

完成本教程后,您将了解:

  • 如何使用 pandas_datareader
  • 如何使用 requests 库调用 Web 服务器的 API
  • 如何生成合成时间序列数据

通过我的新书 Python for Machine Learning 快速启动您的项目,其中包含分步教程以及所有示例的Python 源代码文件。

让我们开始吧。

Picture of sea waves and a bird

Python 数据集处理指南
照片由 Mehreen Saeed 拍摄,部分权利保留

教程概述

本教程分为三个部分;它们是:

  1. 使用 pandas_datareader
  2. 使用 requests 库通过远程服务器的 API 获取数据
  3. 生成合成时间序列数据

使用 pandas-datareader 加载数据

本帖将依赖一些库。如果您的系统中尚未安装它们,可以使用 pip 进行安装

pandas_datareader 库允许您 从不同来源获取数据,包括用于金融市场数据的 Yahoo Finance、用于全球发展数据的 World Bank 以及用于经济数据的 St. Louis Fed。在本节中,我们将展示如何从不同来源加载数据。

在后台,pandas_datareader 实时从网上抓取您想要的数据,并将其组装成 pandas DataFrame。由于网页结构差异很大,每个数据源都需要不同的读取器。因此,pandas_datareader 只支持从有限数量的来源读取,主要是与金融和经济时间序列相关的来源。

获取数据非常简单。例如,我们知道苹果的股票代码是 AAPL,因此我们可以像下面这样从 Yahoo Finance 获取苹果股票的每日历史价格

DataReader() 的调用需要第一个参数指定股票代码,第二个参数指定数据源。上面的代码会打印 DataFrame

我们也可以用股票代码列表来获取多家公司的股票价格历史记录

结果将是一个具有多级列的 DataFrame

由于 DataFrame 的结构,提取部分数据非常方便。例如,我们可以使用以下方法仅绘制某些日期的每日收盘价

从 Yahoo Finance 获取的多只股票

完整代码如下:

使用 pandas-datareader 从另一个数据源读取的语法是类似的。例如,我们可以从 美联储经济数据 (FRED) 读取经济时间序列。FRED 中的每个时间序列都由一个符号标识。例如,所有城市消费者的消费者价格指数是 CPIAUCSL,不包括食品和能源的所有项目的消费者价格指数是 CPILFESL,个人消费支出是 PCE。您可以从 FRED 的网页搜索和查找符号。

下面是如何获取两个消费者价格指数 CPIAUCSL 和 CPILFESL,并在图表中显示它们

消费者价格指数图

从世界银行获取数据也很相似,但我们必须了解世界银行的数据更加复杂。通常,人口等数据系列既是时间序列,也具有国家维度。因此,我们需要指定更多参数来获取数据。

使用 pandas_datareader,我们有一个针对世界银行的特定 API 集。指标的符号可以从 世界银行开放数据中查找,或使用以下方式搜索

search() 函数接受一个正则表达式字符串(例如,上面的 .* 表示任意长度的字符串)。这将打印

其中 id 列是时间序列的符号。

我们可以通过指定 ISO-3166-1 国家代码来读取特定国家的数据。但世界银行也包含非国家聚合(例如,南亚),因此虽然 pandas_datareader 允许我们使用字符串 “all” 来表示所有国家,但我们通常不使用它。下面是如何获取世界银行所有国家和地区的列表

下面是如何获取 2020 年所有国家的人口,并用条形图显示排名前 25 的国家。当然,我们也可以通过指定不同的 startend 年份来获取跨年份的人口数据

不同国家总人口的条形图


想开始学习机器学习 Python 吗?

立即参加我为期7天的免费电子邮件速成课程(附示例代码)。

点击注册,同时获得该课程的免费PDF电子书版本。

使用 Web API 获取数据

除了使用 the pandas_datareader 库之外,有时您也可以选择直接调用其 Web API,无需任何身份验证,直接从 Web 数据服务器获取数据。这可以使用 Python 的标准库 urllib.requests 来完成,或者您也可以使用 requests 库获得更简单的接口。

世界银行就是一个 Web API 可以免费访问的例子,因此我们可以轻松地读取不同格式的数据,例如 JSON、XML 或纯文本。 世界银行数据存储库 API 页面描述了各种 API 及其相应参数。为了重现之前不使用 pandas_datareader 的示例,我们首先构造一个 URL 来读取所有国家/地区的列表,以便找到不是聚合体的国家代码。然后,我们可以使用以下参数构造一个查询 URL

  1. country 参数,值为 all
  2. indicator 参数,值为 SP.POP.TOTL
  3. date 参数,值为 2020
  4. format 参数,值为 json

当然,您可以尝试不同的 指标。默认情况下,世界银行每页返回 50 个条目,我们需要逐页查询才能获取所有数据。我们可以增大每页大小,一次性获取所有数据。下面是如何以 JSON 格式获取国家列表并收集国家代码

它将打印HTTP状态码、头部信息以及国家代码列表,如下所示

从头部信息,我们可以确认我们已经获取了所有数据(第1页,共1页)。然后,我们可以像下面这样获取所有的人口数据

您应该查阅世界银行API文档以了解如何构建URL的详细信息。例如,日期语法2020:2021表示开始和结束年份,额外的参数page=3将为您提供多页结果中的第三页。获取数据后,我们可以仅筛选出非汇总国家的数据,将其放入pandas DataFrame进行排序,然后绘制条形图

图形应该与之前完全相同。但您可以看到,使用pandas_datareader可以使代码更简洁,隐藏了底层操作。

把所有东西放在一起,下面是完整的代码。

使用NumPy创建合成数据

有时,我们可能不想在项目中使用真实世界的数据,因为我们需要一些现实中可能不会发生但特定的东西。一个典型的例子是使用理想的时间序列数据来测试模型。在本节中,我们将学习如何创建合成自回归(AR)时间序列数据。

numpy.random库可用于从不同分布创建随机样本。randn()方法生成具有零均值和单位方差的标准正态分布数据。

在n阶AR(n)模型中,时间步t的值$x_t$取决于前n个时间步的值。即:

$$
x_t = b_1 x_{t-1} + b_2 x_{t-2} + … + b_n x_{t-n} + e_t
$$

其中$b_i$是$x_t$不同**滞后**的系数,误差项$e_t$预计遵循正态分布。

理解了这个公式,我们可以在下面的示例中生成一个AR(3)时间序列。我们首先使用randn()生成序列的前3个值,然后迭代应用上述公式生成下一个数据点。然后,使用randn()函数再次添加一个误差项,该误差项受预定义的noise_level约束

上面的代码将生成如下图形

但是,我们可以通过首先将数据转换为pandas DataFrame,然后添加时间作为索引来进一步添加时间轴

之后,我们将得到以下图形

合成时间序列图

使用类似的技术,我们还可以生成纯随机噪声(即AR(0)序列)、ARIMA时间序列(即具有误差项系数的时间序列)或布朗运动时间序列(即随机噪声的累加和)。

进一步阅读

如果您想深入了解,本节提供了更多关于该主题的资源。

数据源

书籍

总结

在本教程中,您探索了在Python中获取数据或生成合成时间序列数据的各种选项。

具体来说,你学到了:

  • 如何使用pandas_datareader从不同数据源获取金融数据
  • 如何使用requests库调用API从不同的Web服务器获取数据
  • 如何使用NumPy的随机数生成器生成合成时间序列数据

您对本帖讨论的主题有任何疑问吗?请在下方评论区提问,我会尽力回答。

掌握机器学习 Python!

Python For Machine Learning

更自信地用 Python 编写代码

...从学习实用的 Python 技巧开始

在我的新电子书中探索如何实现
用于机器学习的 Python

它提供自学教程数百个可运行的代码,为您提供包括以下技能:
调试性能分析鸭子类型装饰器部署等等...

向您展示高级 Python 工具箱,用于
您的项目


查看内容

, , , , ,

7条关于《Python时间序列数据集获取指南》的回复

  1. Jeremy 2022年3月30日 上午11:21 #

    Mehreen,

    晚上好!这太棒了,尤其是关于开发合成时间序列数据的最后一部分。我处理的是时间序列数据序列,并且一直在使用一种劣等的方法来开发合成数据。虽然时间序列数据本身就很复杂,但时间序列序列会带来额外的复杂性,我可以将其作为指导,使我的数据更加健壮。非常感谢您发布这个!

    保重,
    Jeremy

  2. Imperial Lord Daft Vader 2022年4月1日 下午1:09 #

    关于将时间作为索引添加的先前错误的版本信息
    Python: 3.9.7 (default, Sep 16 2021, 13:09:58)
    [GCC 7.5.0]
    scipy: 1.7.3
    numpy: 1.21.2
    matplotlib: 3.5.1
    pandas: 1.4.1
    statsmodels: 0.13.2
    sklearn: 1.0.2
    theano: 1.0.5
    tensorflow: 2.4.1
    keras: 2.4.3

    • James Carmichael 2022年4月2日 下午12:24 #

      你好……请说明您遇到错误的哪个代码列表。

  3. amit 2022年4月15日 下午1:11 #

    嗨,我收到一个remotedata错误消息!

    我可以在哪里共享日志?

    • James Carmichael 2022年4月16日 上午8:48 #

      嗨 Amit……你能发布确切的错误消息吗?

  4. F.S 2022年5月25日 下午6:30 #

    你好,

    在尝试获取数据时,我收到以下错误消息。
    你能支持一下吗?

    错误消息:ConnectionError: HTTPSConnectionPool(host=’finance.yahoo.com’, port=443): Max retries exceeded with url: /quote/AAPL/history?period1=1609462800&period2=1640998799&interval=1d&frequency=1d&filter=history (Caused by NewConnectionError(‘: Failed to establish a new connection: [Errno 11001] getaddrinfo failed’))

发表回复

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。