当你开始接触丰富多彩的开放数据集时,CSV、JSON和XML等格式名词就会奔涌而来。如何用Python高效地读取它们,为后续的整理和分析作准备呢?本文为你一步步展现过程,你本身也能够动手实践。html
人工智能的算法再精妙,离开数据也是“巧妇难为无米之炊”。python
数据是宝贵的,开放数据尤为珍贵。不管是公众号、微博仍是朋友圈里,许多人一听见“开放数据”、“数据资源”、“数据连接”这些关键词就兴奋不已。git
好不容易拿到了求之不得的数据连接,你会发现下载下来的这些数据,可能有各类稀奇古怪的格式。github
最多见的,是如下几种:算法
你但愿本身能调用Python来清理和分析它们,从而完成本身的“数据炼金术”。数据库
第一步,你先得学会如何用Python读取这些开放数据格式。编程
这篇文章,我们就用实际的开放数据样例,分别为你介绍如何把CSV、XML和JSON这三种常见的网络开放数据格式读取到Python中,造成结构化数据框,方便你的后续分析操做。json
是否是跃跃欲试了?浏览器
咱们选择的开放数据平台,是Quandl。微信
Quandl是一个金融和经济数据平台。其中既包括价格不菲的收费数据,也有很多免费开放数据。
你须要在Quandl免费注册一个帐户,这样才能够正常访问其免费数据集合。
注册过程,只须要填写上面这个表格。注册完毕后,用新帐户和密码登陆。
登陆后,点击首页上的“Core Financial Data”栏目中的“Search Data”。
你立刻就看到让你眼花缭乱的数据集合了。
不要高兴得太早。仔细看数据集合右侧的标签,第一页里基本上都是“Premium”(只限会员),只有付费用户才能使用的。
你不须要本身翻页去查找免费开放数据。点击页面左侧上方的过滤器(Filter)下的“免费”(Free)选项。
此次显示的全都是免费数据了。
这些数据都包含什么内容?若是你感兴趣的话,欢迎本身花点儿时间浏览一下。
我们使用其中的“Zillow Real Estate Research”,这是一个很是庞大的房地产数据集。
Zillow房地产数据都来自于美国城市。你能够根据本身的爱好,选择感兴趣的城市。我选择的是肯塔基州的莱克星顿(Lexington)市。
为何不选纽约、洛杉矶,却要选它呢?
由于我在美国访学的时候,周末常常去那里。
我访问的大学坐落在村子里。本地没有华人超市,一些常见的食品和调料都买不到。
要想去华人超市,就获得最近的“大城市”莱克星顿。
从学校到那里地距离,跟天津到北京差很少。
我本身没有买车,公共交通又不方便,一开始非常苦恼。
好在留学生同胞们周末时常要去莱克星顿逛商场。我老是跟着蹭车。
一个半小时开车进城,咱们先去真正的中餐馆吃一顿自助午饭,而后去商场。他们逛2个小时左右,我找个咖啡馆或者休息区闭目养神,戴着耳机听罗胖讲故事。
等他们逛完了,咱们一块儿去华人超市采购。
这个有大商场、有正牌中餐馆、有多路公交,甚至还有华人超市的“大城市”当初给我留下了难忘的美好回忆。
就拿它当样例吧。
搜索“lexington ky”,返回的结果还真很多。
咱们选择其中的“Zillow Home Value Index (Metro): Home Sales (SA) - Lexington, KY”,点击后能够看到这个数据集的页面。
这是莱克星顿房屋销售价格的中位数(median)在不一样时间的记录。
Quandl已经很周到地帮咱们用折线图绘制了历史价格信息的变化。选择“TABLE”标签页,咱们能够查看原始数据。
下面咱们把数据下载到本地。右上方有个Download按钮,咱们点击它。
能够看到,Quandl提供了咱们4种格式的数据,分别是
这里我们先不讲Excel(由于它是微软的专属格式),只依次下载其余3个类别的数据。
咱们在对应的数据类别上点击鼠标右键,在弹出的浏览器菜单中选择“连接另存为”,而后存储到本地。
我已经为你下载好了相关的3种数据格式,而且存储在了一个Github项目中。请访问这个连接,下载压缩包后,解压查看。
压缩包里,就是莱克星顿市房地产交易信息的三种不一样格式了。从这张图里,能够看到一样的数据内容,csv文件占用空间最小,JSON次之;占空间最大的格式是XML。
数据有了,下面咱们准备一下Python编程环境。
咱们使用Python集成运行环境Anaconda。
请到这个网址 下载最新版的Anaconda。下拉页面,找到下载位置。根据你目前使用的系统,网站会自动推荐给你适合的版本下载。我使用的是macOS,下载文件格式为pkg。
下载页面区左侧是Python 3.6版,右侧是2.7版。请选择2.7版本。
双击下载后的pkg文件,根据中文提示一步步安装便可。
安装好Anaconda后,咱们还须要确保安装几个必要的软件包。
请到你的“终端”(Linux, macOS)或者“命令提示符”(Windows)下面,进入我们刚刚下载解压后的样例目录。
执行如下命令:
pip install json
pip install bs4
复制代码
安装完毕后,执行:
jupyter notebook
复制代码
这样就进入到了Jupyter笔记本环境。咱们新建一个Python 2笔记本。
这样就出现了一个空白笔记本。
点击左上角笔记本名称,修改成有意义的笔记本名“demo-python-read-open-data-formats”。
至此,准备工做作完,下面咱们就能够开始用Python读取不一样格式的数据了。
咱们先从最为简单的CSV格式开始。
所谓CSV,是英文“Comma Separated Values”(逗号分割数值)的简写。
咱们先回到Jupyter Notebook的根目录。
打开我们的样例csv文件,ZILLOW-M550_SALES.csv
来看看。
能够看到,第一行是表头,说明每一列的名称。以后每一行都是数据,分别是日期和对应的售价中位数取值。
每一行的两列数据,都是用逗号来分割的。
咱们能够用Excel来打开csv数据,更直观来看看效果。
如图所示,当咱们用Excel打开csv数据时,Excel自动将其识别为数据表单。逗号不见了,变成了分割好的两列若干行数据。
下面咱们使用Python,将该csv数据文件读入,而且可视化。
读入Pandas工具包。它能够帮助咱们处理数据框,是Python数据分析的基础工具。
import pandas as pd
复制代码
而后,为了让图像能够在Jupyter Notebook上正确显示,咱们使用如下语句,容许页内嵌入图像。
%matplotlib inline
复制代码
下面咱们读入csv文件。Pandas对csv数据最为友好,提供了read_csv
命令,能够直接读取csv数据。
df = pd.read_csv("ZILLOW-M550_SALES.csv")
复制代码
咱们把csv数据存储到了数据框变量df。下面显示一下数据读取效果。
df.head()
复制代码
能够看到,日期和交易价格中位数记录都正确读入。
下面咱们编制一个函数,帮咱们整理数据框。它主要实现如下功能:
def arrange_time_dataframe(df):
df.columns = ['date', 'value']
df.sort_values(by='date', inplace=True)
df.set_index('date', inplace=True)
return df
复制代码
下面咱们调用这个函数,整理数据框变量df。
df = arrange_time_dataframe(df)
复制代码
咱们展现一下df的前5行。
df.head()
复制代码
你会看到,日期数据变成了索引,并且按照升序排列。
下面咱们该绘图了。数据框工具Pandas给咱们提供了很是方便的时间序列图形绘制功能。
为了显示更为美观,咱们把图形的长宽比例作了设置。
df.plot(figsize=(16, 6))
复制代码
对比一下咱们本身绘制的图像和Quandl的示例图形,是否是一致呢?
JSON是JavaScript Object Notation(JavaScript对象标记)的缩写,是一种轻量级的数据交换格式。它跟CSV同样,也是文本文件。
咱们在Jupyter Notebook中打开下载的JSON文件,检视其内容:
咱们须要的数据都在里面,下面咱们回到Python笔记本文件ipynb中,尝试读取JSON数据内容。
首先咱们读取json工具包。
import json
复制代码
打开我们下载的M550_SALES.json
文件,读取数据到变量data。
with open("M550_SALES.json") as f:
data = json.load(f)
复制代码
为了看得更为直观,我们把JSON正确缩进后输出。这里咱们只展现前面的一些行。
print(json.dumps(data, indent=2))
复制代码
{
"dataset": {
"dataset_code": "M550_SALES",
"column_names": [
"Date",
"Value"
],
"newest_available_date": "2016-06-30",
"description": "The Zillow Home Value Index is Zillow's estimate of the median market value of home sales (nsa) within the metro of Morehead City, NC. This data is calculated by Zillow Real Estate Research (www.zillow.com/research) using their database of 110 million homes.",
"end_date": "2016-06-30",
"data": [
[
"2016-06-30",
64.0
],
[
"2016-05-31",
163.0
],
复制代码
能够看到,JSON文件就像是一个大的字典(dictionary)。咱们选择其中的某个索引,就能得到对应的数据。
咱们选择“dataset”:
data['dataset']
复制代码
下面是结果的前几行。
{u'collapse': None,
u'column_index': None,
u'column_names': [u'Date', u'Value'],
u'data': [[u'2016-06-30', 64.0],
[u'2016-05-31', 163.0],
[u'2016-04-30', 118.0],
复制代码
咱们关心的数据在“data”下面。继续来:
data['dataset']['data']
复制代码
仍是只展现前几行:
[[u'2016-06-30', 64.0],
[u'2016-05-31', 163.0],
[u'2016-04-30', 118.0],
复制代码
这不就是咱们想要读取的数据吗?
为了和csv数据作出区分,咱们此次将数据读取后存储在df1变量。
df1 = pd.DataFrame(data['dataset']['data'])
复制代码
显示一下前几行:
df1.head()
复制代码
数据都对,但是列名称怪怪的。
不要紧,咱们刚才不是编制了整理函数吗?无论多么奇怪的列名称,均可以整理好。
df1 = arrange_time_dataframe(df1)
复制代码
整理以后,我们再次调用绘图函数,绘制df1的数据:
df1.plot(figsize=(16, 6))
复制代码
绘图正确,证实咱们的JSON数据读取成功。
XML是扩展标记语言(eXtensible Markup Language)的缩写。它看起来有些像咱们上网时天天都要用到的HTML源码,可是有区别。它的设计初衷,不是为了展现Web页面,而是为了数据交换。
咱们在Jupyter Notebook中打开下载的XML文件。
在页面下方,咱们看到了本身感兴趣的数据部分,可是数据是用不少标签来包裹的。
下面咱们尝试使用Python来提取和整理XML数据。
首先,咱们读入网页分析工具Beautifulsoup。
from bs4 import BeautifulSoup
复制代码
这是一个很是重要的网页信息提取工具,是Python爬虫编写的基础技能之一。
本文只会用到Beautifulsoup的一些简单命令。因此即使你以前从未接触过Beautifulsoup,也没有关系,跟着先作一遍,得到一些感性认知和经验。后面再系统学习。
我建议的系统学习方法,是到Beautifulsoup的文档页面认真阅读和学习。
若是你阅读英文文档有一些困难,能够看翻译好的中文文档,地址在这里。
而后,咱们读入下载好的XML数据,存入变量data。
with open("M550_SALES.xml") as f:
data = f.read()
复制代码
下面咱们用“lxml”工具分析解析data数据,而且存储到soup变量里面。
soup = BeautifulSoup(data, "lxml")
复制代码
解析以后,咱们就能够利用Beautifulsoup的强大搜索功能了。
这里咱们观察XML文件:
能够看到,咱们关心的日期和交易中位数记录存放在datum标签下。
其中,日期数据的类型为“date”,交易价格中位数的类型为“float”。
咱们先来尝试使用Beautifulsoup的find_all
函数,提取全部的日期数据:
dates = soup.find_all('datum', type='date')
复制代码
咱们看看提取结果的前5行:
dates[:5]
复制代码
[<datum type="date">2016-06-30</datum>,
<datum type="date">2016-05-31</datum>,
<datum type="date">2016-04-30</datum>,
<datum type="date">2016-03-31</datum>,
<datum type="date">2016-02-29</datum>]
复制代码
很好,数据正确提取出来。问题是还有标签数据在先后,此时咱们不须要它们。
咱们处理一下。对列表每一项,使用Beautifulsoup的text属性提取内容。
dates = [item.text for item in dates]
复制代码
再看看此次的提取结果:
dates[:5]
复制代码
[u'2016-06-30', u'2016-05-31', u'2016-04-30', u'2016-03-31', u'2016-02-29']
复制代码
好的,没问题了。
下面咱们用一样的方式处理交易价格中位数记录:
values= soup.find_all('datum', type='float')
复制代码
显示一下结果:
values[:5]
复制代码
[<datum type="float">64.0</datum>,
<datum type="float">163.0</datum>,
<datum type="float">118.0</datum>,
<datum type="float">110.0</datum>,
<datum type="float">83.0</datum>]
复制代码
此次仍是有标签,须要去掉。
注意这里咱们但愿把结果存储为浮点数,因此除了用text属性提取数值之外,还用float()
函数作了转换。
values = [float(item.text) for item in values]
复制代码
显示一下前5行:
values[:5]
复制代码
[64.0, 163.0, 118.0, 110.0, 83.0]
复制代码
数据被正确转换成了浮点数。
咱们手里,分别有了日期和交易价格中位数记录列表。下面咱们将其转换成为Pandas数据框,而且存储于df2变量里。
df2 = pd.DataFrame({'dates':dates, 'values':values})
复制代码
看看df2的前几行:
df2.head()
复制代码
数据咱们有了,下面也用咱们的自编函数整理一下:
df2 = arrange_time_dataframe(df2)
复制代码
而后咱们尝试对df2绘图:
df2.plot(figsize=(16, 6))
复制代码
XML数据读取和检视成功。
至此,你已经尝试了如何把CSV、JSON和XML数据读入到Pandas数据框,而且作最基本的时间序列可视化展现。
你可能会有如下疑问:
既然CSV文件这么小巧,Pandas读取起来也方便,为何还要费劲去学那么难用的JSON和XML数据读取方法呢?
这是个好问题!
我能想到的,至少有两个缘由。
首先,我们找到的Quandl平台,全方位提供数据的下载格式,几乎涵盖了所有常见数据格式类别。但这只是特例。大多数的开放数据平台,是不提供这么多种数据格式供你下载的。所以,当你拿到的数据只有JSON或者XML格式时,了解如何读取它们,就很重要。
其次,JSON或XML附加的那些内容,毫不是无心义的。它们能够帮助你检查数据的完整性和合法性。你甚至还能够自行定义语义标准,以便和他人进行高效的数据交换。
若是你对JSON和XML格式感兴趣,但愿系统学习,那我推荐你到Stanford Online这个MOOC平台上学习数据库课程。
祝进步!
你平时从哪些开放数据平台下载过数据?都接触过哪些数据格式?你用什么工具来整理和分析它们呢?有没有比本文更高效的方法?欢迎留言,把你的经验和思考分享给你们,咱们一块儿交流讨论。
喜欢请点赞。还能够微信关注和置顶个人公众号“玉树芝兰”(nkwangshuyi)。
若是你对数据科学感兴趣,不妨阅读个人系列教程索引贴《如何高效入门数据科学?》,里面还有更多的有趣问题及解法。