2Python進階強化訓練之csv|json|xml|excel高
Python進階強化訓練之csv|json|xml|excel高
如何讀寫csv數據?
實際案例
我們可以通過http://table.finance.yahoo.com/table.csv?s=000001.sz,這個url獲取中國股市(深市)數據集,它以csv數據格式存儲:
Date,Open,High,Low,Close,Volume,Adj Close 2016-09-15,9.06,9.06,9.06,9.06,000,9.06 2016-09-14,9.17,9.18,9.05,9.06,42148100,9.06 2016-09-13,9.18,9.21,9.14,9.19,46093100,9.19 2016-09-12,9.29,9.32,9.13,9.16,75658100,9.16 2016-09-09,9.40,9.43,9.36,9.38,32743100,9.38 2016-09-08,9.39,9.42,9.38,9.40,29521800,9.40 2016-09-07,9.41,9.42,9.37,9.40,45937300,9.40 2016-09-06,9.42,9.43,9.36,9.41,57473800,9.41 2016-09-05,9.46,9.46,9.40,9.42,46993600,9.42 2016-09-02,9.43,9.46,9.42,9.45,36879600,9.45 2016-09-01,9.49,9.52,9.42,9.45,48013100,9.45 2016-08-31,9.46,9.50,9.43,9.49,48974600,9.49 2016-08-30,9.42,9.47,9.41,9.47,59508100,9.47 2016-08-29,9.41,9.45,9.38,9.42,56523100,9.42 2016-08-26,9.45,9.47,9.40,9.45,50223300,9.45 2016-08-25,9.42,9.45,9.34,9.44,61738900,9.44 2016-08-24,9.41,9.43,9.38,9.43,73228100,9.43
請將平安銀行這支股票,在2016年中成交量超過14000000
的記錄存儲到另一個csv文件中
解決方案
使用標準庫中的csv模塊,可以使用其中reader
和writer
完成文件讀寫
下載數據
>>> from urllib import urlretrieve # 獲取平安銀行股票信息,保存到pingan.csv文件中 >>> urlretrieve(‘http://table.finance.yahoo.com/table.csv?s=000001.sz‘, ‘pingan.csv‘) (‘pingan.csv‘, <httplib.HTTPMessage instance at 0x1a997e8>)
使用csv模塊進行讀
>>> import csv >>> rf = open(‘pingan.csv‘, ‘rb‘) >>> reader = csv.reader(rf) # 獲取的對象是一個可叠代的 >>> reader.next() [‘Date‘, ‘Open‘, ‘High‘, ‘Low‘, ‘Close‘, ‘Volume‘, ‘Adj Close‘] >>> reader.next() [‘2016-09-15‘, ‘9.06‘, ‘9.06‘, ‘9.06‘, ‘9.06‘, ‘000‘, ‘9.06‘]
使用csv模塊進行寫
>>> wf = open(‘pingan_copy.csv‘, ‘wb‘) >>> writer = csv.writer(wf) >>> writer.writerow([‘2016-09-14‘, ‘9.17‘, ‘9.18‘, ‘9.05‘, ‘9.06‘, ‘42148100‘, ‘9.06‘]) >>> writer.writerow(reader.next()) >>> wf.flush()
查看寫入的文件內容
[[email protected] ~]# cat pingan_copy.csv 2016-09-14,9.17,9.18,9.05,9.06,42148100,9.06 2016-09-13,9.18,9.21,9.14,9.19,46093100,9.19
如上的問題解決方案如下:
#!/use/bin/env python # _*_ coding:utf-8 _*_ import csv with open(‘pingan.csv‘, ‘rb‘) as rf: reader = csv.reader(rf) with open(‘pingan2016.csv‘, ‘wb‘) as wf: writer = csv.writer(wf) headers = reader.next() writer.writerow(headers) for row in reader: if row[0] < ‘2016-01-01‘: break if int(row[5]) >= 50000000: writer.writerow(row)
如何讀寫json數據?
實際案例
在web應用中常用JSON(JavaScript Object Notation)格式傳輸數據,在python中如何讀寫json數據?
解決方案
使用標準庫中的json模塊,其中loads
、dumps
函數可以完成json數據的讀寫
將數據類型轉換為字符串
>>> import json # 創建一個列表 >>> l = [1,2,‘asd‘,{‘blgo_url‘,‘ansheng.me‘}] # 使用dumps轉換為字符串 >>> json.dumps(l) ‘[1, 2, "asd", {"blgo_url": "ansheng.me"}]‘ # 去掉空格 >>> json.dumps(l, separators=[‘,‘,‘:‘]) ‘[1,2,"asd",{"blgo_url":"ansheng.me"}]‘ # 排序 >>> d = {‘b‘:None,‘a‘:‘111‘,‘g‘:‘Null‘} >>> json.dumps(d, sort_keys=True) ‘{"a": "111", "b": null, "g": "Null"}‘
將字符串轉換為數據類型
>>> json.loads(‘[1,2,"asd",{"blgo_url":"ansheng.me"}]‘) [1, 2, ‘asd‘, {‘blgo_url‘: ‘ansheng.me‘}]
如何解析簡單的xml文檔?
實際案例
如以下XML
文檔,如何使用python進行解析?
<?xml version="1.0" encoding="utf-8" ?> <data> <country name="Liechtenstein"> <rank update="yes">2</rank> <year>2008</year> <gdppc>141100</gdppc> <neighbor name="Austria" direction="E"/> <neighbor name="Switzerland" direction="W"/> </country> <country name="Singapore"> <rank update="yes">5</rank> <year>2011</year> <gdppc>59900</gdppc> <neighbor name="Malaysia" direction="N"/> </country> <country name="Panama"> <rank update="yes">69</rank> <year>2011</year> <gdppc>13600</gdppc> <neighbor name="Costa Rica" direction="W"/> <neighbor name="Colombia" direction="E"/> </country> </data>
解決方案
可以使用標準庫中的xml.etree.ElementTree
,其中的parse
函數可以解析XML文檔
# 導入parse >>> from xml.etree.ElementTree import parse >>> f = open(‘a.xml‘) # 獲得ElementTree對象 >>> et = parse(f) # 獲取根節點,也就是data >>> root = et.getroot() >>> root <Element ‘data‘ at 0x00000203ECA1E728> # 查看標簽 >>> root.tag ‘data‘ # 屬性 >>> root.attrib {} # 文本 >>> root.text.strip() ‘‘ # 獲得一個節點的子元素,然後在獲取每個子元素的屬性 >>> for child in root: print(child.get(‘name‘)) ... Liechtenstein Singapore Panama # 根據標簽尋找子元素,每次之尋找第一個 >>> root.find(‘country‘) <Element ‘country‘ at 0x00000203ECBD3228> # 尋找所有 >>> root.findall(‘country‘) [<Element ‘country‘ at 0x00000203ECBD3228>, <Element ‘country‘ at 0x00000203ECBDBC28>, <Element ‘country‘ at 0x00000203ECBDBDB8>] # 獲得一個生成器對象 >>> root.iterfind(‘country‘) <generator object prepare_child.<locals>.select at 0x00000203ECBC5FC0> >>> for e in root.iterfind(‘country‘): print(e.get(‘name‘)) ... Liechtenstein Singapore Panama # 獲取所有的元素節點 >>> list(root.iter()) [<Element ‘data‘ at 0x00000203ECA1E728>, <Element ‘country‘ at 0x00000203ECBD3228>, <Element ‘rank‘ at 0x00000203ECBDBA98>, <Element ‘year‘ at 0x00000203ECBDBAE8>, <Element ‘gdppc‘ at 0x00000203ECBDBB38>, <Element ‘neighbor‘ at 0x00000203ECBDBB88>, <Element ‘neighbor‘ at 0x00000203ECBDBBD8>, <Element ‘country‘ at 0x00000203ECBDBC28>, <Element ‘rank‘ at 0x00000203ECBDBC78>, <Element ‘year‘ at 0x00000203ECBDBCC8>, <Element ‘gdppc‘ at 0x00000203ECBDBD18>, <Element ‘neighbor‘ at 0x00000203ECBDBD68>, <Element ‘country‘ at 0x00000203ECBDBDB8>, <Element ‘rank‘ at 0x00000203ECBDBE08>, <Element ‘year‘ at 0x00000203ECBDBE58>, <Element ‘gdppc‘ at 0x00000203ECBDBEA8>, <Element ‘neighbor‘ at 0x00000203ECBDBEF8>, <Element ‘neighbor‘ at 0x00000203ECBDBF48>] # 尋找標簽為rank的子節點 >>> list(root.iter(‘rank‘)) [<Element ‘rank‘ at 0x00000203ECBDBA98>, <Element ‘rank‘ at 0x00000203ECBDBC78>, <Element ‘rank‘ at 0x00000203ECBDBE08>]
查找的高級用法
# 匹配country下的所有子節點 >>> root.findall(‘country/*‘) [<Element ‘rank‘ at 0x00000203ECBDBA98>, <Element ‘year‘ at 0x00000203ECBDBAE8>, <Element ‘gdppc‘ at 0x00000203ECBDBB38>, <Element ‘neighbor‘ at 0x00000203ECBDBB88>, <Element ‘neighbor‘ at 0x00000203ECBDBBD8>, <Element ‘rank‘ at 0x00000203ECBDBC78>, <Element ‘year‘ at 0x00000203ECBDBCC8>, <Element ‘gdppc‘ at 0x00000203ECBDBD18>, <Element ‘neighbor‘ at 0x00000203ECBDBD68>, <Element ‘rank‘ at 0x00000203ECBDBE08>, <Element ‘year‘ at 0x00000203ECBDBE58>, <Element ‘gdppc‘ at 0x00000203ECBDBEA8>, <Element ‘neighbor‘ at 0x00000203ECBDBEF8>, <Element ‘neighbor‘ at 0x00000203ECBDBF48>] # 找到所有節點的rank >>> root.findall(‘.//rank‘) [<Element ‘rank‘ at 0x00000203ECBDBA98>, <Element ‘rank‘ at 0x00000203ECBDBC78>, <Element ‘rank‘ at 0x00000203ECBDBE08>] # 找到rank的父對象 >>> root.findall(‘.//rank/..‘) [<Element ‘country‘ at 0x00000203ECBD3228>, <Element ‘country‘ at 0x00000203ECBDBC28>, <Element ‘country‘ at 0x00000203ECBDBDB8>] # 查找country包含name屬性的 >>> root.findall(‘country[@name]‘) [<Element ‘country‘ at 0x00000203ECBD3228>, <Element ‘country‘ at 0x00000203ECBDBC28>, <Element ‘country‘ at 0x00000203ECBDBDB8>] >>> root.findall(‘country[@age]‘) [] # 查找屬性等於特定值的元素 >>> root.findall(‘country[@name="Singapore"]‘) [<Element ‘country‘ at 0x00000203ECBDBC28>] # 查找必須包含某一個子元素 >>> root.findall(‘country[rank]‘) [<Element ‘country‘ at 0x00000203ECBD3228>, <Element ‘country‘ at 0x00000203ECBDBC28>, <Element ‘country‘ at 0x00000203ECBDBDB8>] # 查找子元素等於指定的值 >>> root.findall(‘country[rank="5"]‘) [<Element ‘country‘ at 0x00000203ECBDBC28>] # 根據位置查找,從1開始 >>> root.findall(‘country‘) [<Element ‘country‘ at 0x00000203ECBD3228>, <Element ‘country‘ at 0x00000203ECBDBC28>, <Element ‘country‘ at 0x00000203ECBDBDB8>] # 根據位置查找 >>> root.findall(‘country[1]‘) [<Element ‘country‘ at 0x00000203ECBD3228>] # 倒數第一個 >>> root.findall(‘country[last()]‘) [<Element ‘country‘ at 0x00000203ECBDBDB8>] # 倒數第二個 >>> root.findall(‘country[last()-1]‘) [<Element ‘country‘ at 0x00000203ECBDBC28>]
如何構建xml文檔?
實際案例
某些時候,我們需要將其他格式數據轉換為xml,例如下面的字符串如何轉換為XML?
z
解決方案
使用標準庫中的xml.etree.ElementTree
,構建ElementTree
,使用write
方法寫入文件
>>> from xml.etree.ElementTree import Element, ElementTree >>> from xml.etree.ElementTree import tostring >>> e = Element(‘Data‘) >>> e.set(‘name‘, ‘abc‘) >>> e.text = ‘123‘ # 查看結果 >>> tostring(e) b‘<Data name="abc">123</Data>‘ >>> e2 = Element(‘Row‘) >>> e3 = Element(‘Open‘) >>> e3.text = ‘9.17‘ >>> e2.append(e3) >>> e.text = None >>> e.append(e2) >>> tostring(e) b‘<Data name="abc"><Row><Open>9.17</Open></Row></Data>‘ >>> et = ElementTree(e) >>> et.write(‘demo.xml‘)
解決如上問題的腳本如下:
import csv from xml.etree.ElementTree import Element, ElementTree def pretty(e, level=0): if len(e) > 0: e.text = ‘\n‘ + ‘\t‘ * (level + 1) for child in e: pretty(child, level + 1) child.tail = child.tail[:-1] e.tail = ‘\n‘ + ‘\t‘ * level def csvToXML(fname): with open(fname, ‘rb‘) as f: reader = csv.reader(f) headers = reader.next() root = Element(‘Data‘) for row in reader: eRow = Element(‘Row‘) root.append(eRow) for tag, text in zip(headers, row): e = Element(tag) e.text = text eRow.append(e) pretty(root) return ElementTree(root) et = csvToXML(‘pingan.csv‘) et.write(‘pingan.xml‘)
轉換好的文件內容為:
<Data> <Row> <Date>2016-09-15</Date> <Open>9.06</Open> <High>9.06</High> <Low>9.06</Low> <Close>9.06</Close> <Volume>000</Volume> <Adj Close>9.06</Adj Close> </Row> <Row> <Date>2016-09-14</Date> <Open>9.17</Open> <High>9.18</High> <Low>9.05</Low> <Close>9.06</Close> <Volume>42148100</Volume> <Adj Close>9.06</Adj Close> </Row> .....
如何讀寫excel文件?
實際案例
Microsoft Excel是日常辦公中使用最頻繁的軟件,起數據格式為xls,xlsx,一種非常常用的電子表格。
某小學某班成績記錄在excel了文件中,內容如下:
姓名 語文 數學 外語 小明 95 96 94 張三 85 84 92 王五 86 85 75 小哈 96 92 100
利用python讀寫excel了,添加總分列,計算每人總分
解決方案
使用第三方庫xlrd和xlwt,這兩個庫分別用於excel讀和寫
安裝這兩個模塊
pip3 install xlrd pip3 install xlwt
腳本如下:
#!/usr/bin/env python # _*_ coding:utf-8 _*_ # 導入xlrd和xlwt import xlrd import xlwt # 打開excel文件 rbook = xlrd.open_workbook(‘x.xlsx‘) # 表 rsheet = rbook.sheet_by_index(0) # 添加一個總分的列 # 列 nc = rsheet.ncols # 第0行,列,文本類型,文字,內容 rsheet.put_cell(0, nc, xlrd.XL_CELL_TEXT, ‘總分‘, None) # 叠代表中的所有數據,計算總分 for row in range(1, rsheet.nrows): # 計算每行的總分,跳過第0行,0==姓名,sum對列表進行求和,t等於最後加上拿出來的分數 t = sum(rsheet.row_values(row, 1)) # 寫入數據 rsheet.put_cell(row, nc, xlrd.XL_CELL_NUMBER, t, None) # 寫入到文件中 wbook = xlwt.Workbook() wsheet = wbook.add_sheet(rsheet.name) # 對其方式,垂直和水平都是劇中 style = xlwt.easyxf(‘align: vertical center, horizontal center‘) # rsheet的每個單元格寫入到wsheet中 for r in range(rsheet.nrows): # 行 for c in range(rsheet.ncols): # 列 wsheet.write(r, c, rsheet.cell_value(r, c), style) wbook.save(‘output.xlsx‘)
計算結果如下:
姓名 語文 數學 外語 總分 小明 95 96 94 285 張三 85 84 92 261 王五 86 85 75 246 小哈 96 92 100 288
#Python
本文出自 “Eden” 博客,轉載請與作者聯系!
2Python進階強化訓練之csv|json|xml|excel高