作者:王树义 链接:https://www.jianshu.com/p/424e1c65f424 來源:简书
分别介绍如何把 CSV/XML/JSON这三种常见的网络开放数据格式读取到python,形成结构化数据框,方便后续分析操作。
csv: comma separated values 逗号分隔数值
jupyter notebook中:
- 打开文件
!cat + 文件名
- 为了让图像在 Jupyter Notebook 上正确显示,使用以下语句,允许页内嵌入图像
%matplotlib inline
pandas 对csv的数据最为友好,提供了read_csv方法,直接读取csv数据。
df = pd.read_csv("ZILLOW-M550_SALES.csv")
我们把csv数据存储到了数据框变量df。下面显示一下数据读取效果。
inplace=True 表示的是在原地进行处理:下面我们编制一个函数,帮我们整理数据框。它主要实现以下功能:
- 把列名变成小写的“date”和“value”;
- 按照时间顺序,排列数据。把最旧的日期和对应的数值放在第一行,最新的日期和对应的数值置于末尾;
- 把时间设置为数据框的索引,这主要是便于后面绘图的时候,横轴正确显示日期数据。
def arrange_time_dataframe(df): df.columns = ['date', 'value'] df.sort_values(by='date', inplace=True) df.set_index('date', inplace=True) return df
inplace : bool, default False if True, perform operation in-place
下面我们调用这个函数,整理数据框变量df。
df = arrange_time_dataframe(df)
我们展示一下df的前5行。
df.head()
你会看到,日期数据变成了索引,而且按照升序排列。
下面我们该绘图了。数据框工具Pandas给我们提供了非常方便的时间序列图形绘制功能。
为了显示更为美观,我们把图形的长宽比例做了设置。
df.plot(figsize=(16, 6))
可以看见df.plot() 此时plot是一个pandas方法
json: javascript object nonation(JavaScript对象标记)
首先我们读取json工具包。
import json
打开咱们下载的M550_SALES.json
文件,读取数据到变量data。
with open("M550_SALES.json") as f:
data = json.load(f)
#data = f.read()
print(f)
<_io.TextIOWrapper name='M550_SALES.json' mode='r' encoding='UTF-8'>
为了看得更为直观,咱们把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))
XML:eXtensible Markup Language--扩展标记语言
在页面下方,我们看到了自己感兴趣的数据部分,但是数据是用很多标签来包裹的。
下面我们尝试使用Python来提取和整理XML数据。
首先,我们读入网页分析工具Beautifulsoup。
from bs4 import BeautifulSoup
这是一个非常重要的网页信息提取工具,是Python爬虫编写的基础技能之一。
下面我们用“lxml”工具分析解析data数据,并且存储到soup变量里面。
soup = BeautifulSoup(data, "lxml")
解析之后,我们就可以利用Beautifulsoup的强大搜索功能了。
可以看到,我们关心的日期和交易中位数记录存放在datum标签下。
其中,日期数据的类型为“date”,交易价格中位数的类型为“float”。
我们先来尝试使用Beautifulsoup的find_all
函数,提取所有的日期数据:
我们先来尝试使用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 是一个列表,列表的元素就是一个存储日期的结构,然后使用列表推倒式,重要的是text 这个算是方法吧,与xpath有一点点不同,在后者里面 要用text()才能得到标签的内容。
再看看这次的提取结果:
dates[:5]
[u'2016-06-30', u'2016-05-31', u'2016-04-30', u'2016-03-31', u'2016-02-29']
当然,这次的dates 还是一个列表。
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]
数据被正确转换成了浮点数。
df2 = pd.DataFrame({'dates':dates, 'values':values})
看看df2的前几行:
df2.head()
数据我们有了,下面也用我们的自编函数整理一下:
df2 = arrange_time_dataframe(df2)
然后我们尝试对df2绘图:
df2.plot(figsize=(16, 6))