本章的重點是利用Python來處理各種常見的編碼形式所呈現(xiàn)的數(shù)據(jù)蟀给;比如CSV文件,JSON,XML以及二進制形式的打包記錄驻民。
1.讀取CSV數(shù)據(jù)
解決方案:對于大部分的csv數(shù)據(jù)绽左,都可以使用csv庫來處理悼嫉;
Python tablib模塊是第三方模塊,主要作用是將數(shù)據(jù)導出為各種不同的格式拼窥,包括excel戏蔑,json蹋凝,html,yaml总棵,csv鳍寂,tsv等格式
>>> import csv
>>> with open('d:\\cbs.csv') as f:
... f_csv = csv.reader(f)
... headers = next(f_csv)
... for row in f_csv:
... print(row)
...
['bdsa_growth_track', ' stat_dt', ' 時間']
['bdsa_growth_track', ' cust_mng_emp_id', ' 客戶經(jīng)理工號']
['bdsa_growth_track', ' cust_mng_emp_nm', ' 客戶經(jīng)理姓名']
如果我們的目標是讀取csv數(shù)據(jù)來進行數(shù)據(jù)分析和統(tǒng)計,那么應該看看Pandas這個Python包情龄,Pandas中有一個方便的函數(shù)pandas.read_csv()迄汛,能夠?qū)sv數(shù)據(jù)加載到DataFrame對象中,之后便可以生成各種各樣的統(tǒng)計摘要了骤视,還可以對數(shù)據(jù)進行篩選并執(zhí)行其他類型的高級操作鞍爱;
2.讀取json數(shù)據(jù)
解決方案:json模塊中提供了一種簡單的方法來編碼和解碼JSON個數(shù)的數(shù)據(jù),這兩個主要的函數(shù)是json.dumps()和json.loads()专酗。這兩個函數(shù)在命名上借鑒了其他序列化處理庫的接口睹逃,比如pickle。
如果要同文件而不是字符串打交道的話祷肯,可以選擇使用json.dump()以及json.load()來編碼和解碼JSON數(shù)據(jù)沉填;
>>> json.dumps(False)
'false'
>>> d = {'a':True,'b':False,'c':None}
>>> json.dumps(d)
'{"a": true, "b": false, "c": null}'
如果要檢查從JSON中解碼的得到的數(shù)據(jù),那么斤斤將其打印出來就想確定數(shù)據(jù)的結(jié)果通常是比較困難的--尤其是如果數(shù)據(jù)中包含可深層次的嵌套結(jié)果或者有許多字段時躬柬,為了幫助解決這個問題拜轨,考慮使用pprint模塊中的pprint()函數(shù);
>>>from urllib.request import urlopen
>>>import json
>>>u = urlopen('http://search.twitter.com/search.json/q=python&rpp=5')
>>>resp = json.load(u.read().decode('utf-8'))
>>>from pprint import pprint
>>>pprint(resp)
一般情況下允青,JSON解碼是會從所提供的數(shù)據(jù)中創(chuàng)建出字典或者列表橄碾,如果想創(chuàng)建其他類型的對象,可以為json.loads()提供object_pairs_hook或者object_hook參數(shù)颠锉。例如我們需要將JSON數(shù)據(jù)解碼為(OrderedDict)有序字典
>>> s = '{"name":"overad","shares":50,"price":490.1}'
>>> from collections import OrderedDict
>>> data = json.loads(s,object_pairs_hook = OrderedDict)
>>> data
OrderedDict([('name', 'overad'), ('shares', 50), ('price', 490.1)])
可以將JSON字典轉(zhuǎn)換為Python對象
>>> class JSONObject:
... def __init__(self,d):
... self.__dict__ = d
...
>>> data = json.loads(s,object_hook = JSONObject)
>>> data.name
'overad'
>>> data.shares
50
有幾個選項對于編碼JSON來說是很有用的法牲,如果想讓輸出格式變得漂亮一些,可以在json.dumps()函數(shù)中使用indent參數(shù)琼掠。這個會使得數(shù)據(jù)能夠像pprint()函數(shù)那樣以漂亮的格式打印出來
>>> print(json.dumps(s,indent=4))
如果想在輸出中對鍵進行排序處理拒垃,可以使用sort_keys
參數(shù)
>>> print(json.dumps(s,sort_keys = True))
3.解析簡單的XML文檔
解決方案:xml.etree.ElementTree模塊可以用來從簡單的XML文檔中提取出數(shù)據(jù),
為了說明瓷蛙,假設想對Planet Python上的訂閱RSS做解析并生成一個總結(jié)報告悼瓮。
>>> from urllib.request import urlopen
>>> from xml.etree.ElementTree import parse
>>> u = urlopen('http://planet.python.org/rss20.xml')
>>> doc = parse(u)
>>> for item in doc.iterfind('channel/item'):
... title = item.findtext('title')
... date = item.findtext('pubDate')
... link = item.findtext('link')
... print(title)
... print(date)
... print(link)
... print()
...
Trey Hunner: Multiple assignment and tuple unpacking improve Python code readability
Thu, 08 Mar 2018 00:30:00 +0000
http://treyhunner.com/2018/03/tuple-unpacking-improves-python-code-readability/
Mauveweb: Pyweek Game Jam, Episode 25
Thu, 08 Mar 2018 00:27:53 +0000
http://mauveweb.co.uk/posts/2018/03/pyweek-25.html
xml.etree.ElementTree.parse()
函數(shù)將整個XML文檔解析為一個文檔對象。之后就可以利用find(),iterfind()和findtext()方法
查詢特定XML元素艰猬,這些函數(shù)的參數(shù)就是特定的標簽名稱横堡;
每個由ElementTree模塊所表示的元素都有一些重要的屬性和方法,他們對解析操作十分有用冠桃,tag屬性包含了標簽的名稱命贴,text屬性中包含有附著的文本,而get()方法可以用來提取出屬性,
>>> doc
<xml.etree.ElementTree.ElementTree object at 0x0000000003C0CA58>
>>> e = doc.find('channel/title')
>>> e
<Element 'title' at 0x0000000003F86C28>
>>> e.tag
'title'
>>> e.text
'Planet Python'
>>> e.get('title')
應該指出的是胸蛛,xml.etree.ElementTree并不是解析XML的唯一選擇污茵,對于更加高級的應用,應該考慮使用lxml葬项,lxml采用的編程接口和ElementTree一樣泞当,導入語句為,from lxml.etree import parse
玷室;
4.以增量方式解析大型XML文檔
解決方案:任何情況下零蓉,當要面對以增量方式來處理數(shù)據(jù)的問題時,都應該考慮使用迭代器和生成器穷缤。
from xml.etree.ElementTree import iterparse
5.將字典解析為XML
盡管xml.etree.ElementTree庫通常用來解析XML文檔,但他同時也可以用來創(chuàng)建XML文檔箩兽,
>>> from xml.etree.ElementTree import Element
>>> def dict_to_xml(tag,d):
... elem = Element(tag)
... for key,val in d.items():
... child = Element(key)
... child.text = str(val)
... elem.append(child)
... return elem
...
>>> s = {'name':'overad','shares':100,'price':490.1}
>>> e = dict_to_xml('stock',s)
>>> e
<Element 'stock' at 0x000000000A8D8E58>
>>> from xml.etree.ElementTree import tostring
>>> tostring(e)
b'<stock><name>overad</name><shares>100</shares><price>490.1</price></stock>'
如果想為元素附加上屬性津肛,可以使用set()方法實現(xiàn);
>>> e.set('_id','12345')
>>> tostring(e)
b'<stock _id="12345"><name>overad</name><shares>100</shares><price>490.1</price></stock>'
6.解析汗贫、修改和重寫XML
解決方案:修改XML文檔的結(jié)果是簡單直接的身坐,但是必須記住所有的修改主要是對父元素進行的,我們把他當做一個列表一樣對待落包。比如要移除某個元素部蛇,那么久利用它的直接父節(jié)點的remove()方法完成。如果要插入或添加新元素咐蝇,統(tǒng)一要使用父節(jié)點的insert()和append()方法來完成涯鲁。這些元素也可以使用索引和切片來進行操作,比如element[i]或者是element[i:j]
7.用命名空間來解析XML文檔
8.同關系型數(shù)據(jù)庫進行交互
9.編碼和解碼十六進制數(shù)字
10.Base64編碼和解碼
11.讀寫二進制結(jié)構的數(shù)組
12.讀取嵌套和大小可變的二進制結(jié)構
13.數(shù)據(jù)匯總和統(tǒng)計
解決方案:Pandas