Python数据科学实战
上QQ阅读APP看书,第一时间看更新

1.2 数据来源

既然现在你已经知道了数据的主要类别,那么你可能会从哪些地方获取数据呢?一般来说,数据有各种不同的来源,包括文本、视频、图像、传感器等。但是,从你将要写的Python脚本的角度来看,常见的数据源有如下4种:

 应用程序接口(Application Program Interface,API);

 网页;

 数据库;

 文件。

当然,上面列的数据来源并不全面,Python脚本能够处理的数据不只限于这几种。在实际中,还有许多其他数据来源。

从技术上来说,这里列出的所有选项要求用户使用相应的Python库。例如,从API获取数据之前,需要为API安装Python包装器,或者使用Python库Requests直接向API发出HTTP请求。同样,为了访问某数据库的数据,需要在Python代码中安装一个连接器,使用户能够访问该数据库。

虽然许多库是必须下载和安装的,但一些用于加载数据的库是Python默认分配的。例如,要从JSON文件加载数据,可以使用Python内置的json包。

在第4章和第5章中,我们将学习如何使用Python从不同来源加载特定类型的数据,以便进一步处理。下面将简要介绍前面提到的常见数据源。

1.2.1 API

现在获取数据最常见的方式可能是使用API(Application Program Interface,应用程序接口)。要在Python中使用API,可能需要以Python库的形式为该API安装包装器。现在常用的安装方式是通过pip命令。

虽然并不是所有API都有自己的Python包装器,但是这并不一定意味着你不能从Python访问它们。如果一个API服务于HTTP请求,那么你可以在Python中使用Python库Requests与该API进行交互。这将让你可以使用Python代码从成千上万的API中请求数据并做进一步处理。

当你为特定任务选择一个API时,你需要考虑以下几个因素。

 功能。许多API能提供类似的功能,因此你需要了解自己的确切需求。例如,许多API允许你从Python脚本进行Web搜索,但只有一些API允许你按发布日期缩小搜索范围。

 成本。许多API允许你使用所谓的开发人员密钥,该密钥通常是免费提供的,但有一定的限制,如限制每天的调用次数。

 稳定性。由于有Python包索引(Python Package Index,PyPI)存储库,因此任何人都可以将API打包为一个pip包,并公开发布。因此,对于你能想象到的几乎任何任务,都有一个(或几个)API,但并非所有这些都是完全可靠的。幸运的是,PyPI存储库可以跟踪包的性能和使用情况。

 说明文档。流行的API通常有一个相应的文档网站,允许你查看所有的API命令,并有示例用法。Nasdaq Data Link(又名Quandl)API是一个很好的示例,请查看Nasdaq Data Link的文档页面,在那里可以找到多种时间序列调用的示例。

许多API返回的结果保存为JSON、XML或CSV这3种格式之一。这些格式中的任何一种都可以轻松地将数据转换为Python内置或常用的数据结构。例如,Yahoo Finance API检索并分析股票数据,然后返回结果,且结果是pandas数据框。pandas数据框是一种广泛使用的结构,这将在第3章中讨论。

1.2.2 网页

网页可以是静态的,为了响应用户的交互,网页也可以是动态生成的,在这种情况下,它们可能包含来自多个不同来源的信息。无论哪种情况,程序都可以读取网页并提取部分内容。这称为网络抓取,只要网页是公开的,这就是合法的。

Python中一个典型的抓取流程涉及两个库——Requests库和BeautifulSoup库。使用Requests库获取网页的源代码,使用BeautifulSoup库为页面创建解析树,即页面内容的分层表示。你可以搜索解析树,并使用Python从中提取数据。例如,以下是解析树的片段。

[<td title="03/01/2020 00:00:00"><a href="Download.aspx?ID=630751" id="lnkDownload630751"
 target="_blank">03/01/2020</a></td>,
<td title="03/01/2020 00:00:00"><a href="Download.aspx?ID=630753" id="lnkDownload630753"
 target="_blank">03/01/2020</a></td>,
<td title="03/01/2020 00:00:00"><a href="Download.aspx?ID=630755" id="lnkDownload630755"
target="_blank">03/01/2020</a></td>]

使用Python的for循环可以轻松地把解析树变换为如下列表。

[
  {'Document_Reference': '630751', 'Document_Date': '03/01/2020',
   'link': '**** *** **** dummy ****/Download.aspx?ID=630751'}
  {'Document_Reference': '630753', 'Document_Date': '03/01/2020',
   'link': '**** *** **** dummy **** /Download.aspx?ID=630753'}
  {'Document_Reference': '630755', 'Document_Date': '03/01/2020',
   'link': '**** *** **** dummy **** /Download.aspx?ID=630755'}
]

这是一个将半结构化数据变换为结构化数据的示例。

1.2.3 数据框

除网页之外,另一种常见的数据源是关系数据库,这种结构提供了一种高效地存储、访问和操作结构化数据的机制。你可以使用结构化查询语言(Structured Query Language,SQL)从数据库的表中获取数据或将数据的一部分发送到表中。例如,向数据库中的employees表发出的以下请求只检索在IT部门工作的程序员的列表,因此无须获取整个表。

SELECT first_name, last_name FROM employees WHERE department = 'IT' and title = 'programmer'

Python有一个内置的数据库引擎——SQLite。或者,你可以使用任何其他可用的数据库。在访问数据库之前,你需要在环境中安装数据库客户端软件。

除传统的严格结构化数据库之外,近年来,人们越来越需要在类似于数据库的容器中存储异构数据和非结构化数据。这使得所谓的NoSQL(non-SQL或者not only SQL)数据库越来越流行。NoSQL数据库使用灵活的数据模型,允许你使用键值(key-value)方法存储大量非结构化数据,其中每一段数据都可以使用关联的键访问。之前的示例中的财务报表可以用如下格式存储在NoSQL数据库中。

key   value
---   -----
...
26    GoodComp shares soared as much as 8.2% on 2021-01-07 after the company announced ...

整个财务报表的文本与键26配对。将整个语句存储在数据库中似乎有些奇怪。然而,回想一下,我们可以从一个文本中提取几条不同的记录。存储整个语句使我们能够灵活地在以后提取不同的信息。

1.2.4 文件

文件可能包含结构化数据、半结构化数据和非结构化数据。Python的内置函数open()允许你打开文件,以便在脚本中使用其数据。但是,根据数据的格式(如CSV、JSON或XML),你可能需要导入相应的库才能对其执行读、写或者追加等操作。

纯文本文件在Python中被视为字符序列,不需要其他库即可进一步处理。下面的示例是思科路由器可能会发送到日志文件的信息。

dat= 'Jul 19 10:30:37'
host='sm1-prt-highw157'
syslogtag='%SYS-1-CPURISINGTHRESHOLD:'
msg=' Threshold: Total CPU Utilization(Total/Intr): 17%/1%,
Top 3 processes(Pid/Util): 85/9٪, 146/4٪, 80/1٪'

你可以逐行阅读上面的日志文件,以寻找所需的信息。因此,如果你的任务是查找包含CPU利用率的信息,并从中提取特定的数字,那么你的脚本应该将代码段中的最后一行识别为要选择的信息。