Python資料讀寫
阿新 • • 發佈:2018-12-21
資料處理過程中常用到的資料檔案格式有txt,csv,excel,xml,資料庫。本文的應用物件是資料處理,所以我們關注的是結構化資料。至於基礎的文字讀寫不在本文的討論範圍。對於不同型別的資料,我們用到的工具也不同。
- txt,csv通常儲存關係型資料,也就是是可以用二維陣列表示。對於這一類資料,我們一般使用pandas讀寫。所以這裡介紹pandas內建的函式處理方法。
- excel也可以儲存關係型資料,但對比csv可以設計更復雜的結構。我們使用xlrd讀取,xlwt寫入。
- xml可以儲存多層級的資料,例如描述一個物件時需要多層次,多維度的資料。Python支援兩種機制——SAX和minidom。SAM是基於事件響應機制的,也就是順序讀取xml檔案,發現一個節點就會呼叫相關函式。而minidom是根據xml整個檔案建立一個樹形結構,然後提供遍歷搜尋的方法。我們這裡介紹minidom方法。
- 資料庫是管理資料的專業工具,特別適用於多人共享資料的場合。本文介紹Python對MySQL資料庫的讀寫。實際上Python對SQLite資料庫的支援更好。但是SQLite實際上只是使用SQL語句操作檔案。如果只是想鍛鍊SQL語言,開發又只限於本地,SQLite倒是個不錯的選擇。
txt文字資料讀取
pandas可以使用函式read_table()讀取txt檔案
import pandas as pd
# 根據正則解析來辨識間隔符號
txtframe = pd.read_table('./Data/tmp_4.txt',sep=r'\s+')
print(txtframe, "\n-----*-----")
txtframe = pd.read_table('./Data/tmp_4.txt',sep=r'\s+',header=None,engine='python')
print(txtframe, "\n-----*-----")
# 使用skiprows選項,可以排除多餘的行。把要排除的行的行號放到陣列中,賦給該選項即可。
txtframe = pd.read_table('./Data/tmp_4.txt',sep=r'\s+',skiprows=[3,4])
txtframe = txtframe.reset_index( drop=True)
print(txtframe)
我沒有找到pandas對txt的寫入檔案,實際上csv和txt是共通的,我們可以用to_csv函式來寫入txt檔案。但還是有點不專業。這裡補充numpy對txt檔案的處理。
import numpy as np
data = np.loadtxt('./Data/tmp_2.csv',delimiter=',')
print(data)
np.savetxt('./Data/tmp_7.txt',data,fmt='%d',delimiter=',',newline='\n')
csv檔案讀寫
pandas支援多種資料讀寫方法,這裡列舉一些方法。
讀取 | 寫入 | 資料檔案 |
---|---|---|
read_clipboard | to_clipboard | 從剪貼簿中讀寫 |
read_csv | to_csv | CSV |
read_excel | to_excel | Excel |
read_sql | to_sql | |
read_pickle | to_pickle | |
read_json | to_json | |
read_msgpack | to_msgpack | |
read_stata | to_stata | |
read_gbq | to_gbq | 從Google BigQuery載入資料 |
read_hdf | to_hdf | |
read_html | to_html | |
read_parquet | to_parquet | |
read_feather | to_feather |
pandas中read_csv()和to_csv()可以處理csv檔案
import pandas as pd
a = np.arange(1,26,1)
a = a.reshape((5,5))
b = pd.DataFrame(a,columns=['i1','i2','i3','i4','i5'])
#!!!寫入檔案
b.to_csv('./Data/tmp_1.csv')
# 使用index和 header選項,把它們的值設定為False,可取消預設寫入index和header
b.to_csv('./Data/tmp_2.csv',index =False,header=False)
# 可以用to_csv()函式的na_rep選項把空欄位替換為你需要的值。常用值有NULL、0和NaN
b.to_csv('./Data/tmp_3.csv',na_rep="空")
#!!!讀取檔案
csvframe = pd.read_csv('./Data/tmp_1.csv')
print(csvframe, "\n-----*-----")
csvframe = pd.read_table('./Data/tmp_1.csv',sep=',')
print(csvframe, "\n-----*-----")
# 設定header為None,表示檔案沒有表頭,第一行為資料,新增預設表頭
csvframe = pd.read_csv('./Data/tmp_2.csv',header=None)
print(csvframe, "\n-----*-----")
# 指定表頭。我們假設檔案中有m列資料,設定的names有n個列名。
# 如果m>n,預設從最後一列(右側)開始匹配,多餘的右側第一列作為index,其餘資料捨棄
# 如果m==n,正常匹配
# 如果m<n,預設從第一列(左側)開始匹配,多餘的列名全部賦值Nan
csvframe = pd.read_csv('./Data/tmp_2.csv',names=['d1','d2','d3','d4','d5','d6'])
print(csvframe, "\n-----*-----")
#等級索引,可以指定以某一列為索引,支援多列索引。
csvframe = pd.read_csv('./Data/tmp_3.csv',index_col=['i1','i2'])
print(csvframe, "\n-----*-----")
excel檔案讀寫
使用xlrd讀取excel讀取資料
import xlrd
# 設定路徑
path = './Data/1.xlsx'
# 開啟execl
workbook = xlrd.open_workbook(path)
# 輸出Excel檔案中所有sheet的名字
print(workbook.sheet_names())
# 根據sheet索引或者名稱獲取sheet內容
Data_sheet = workbook.sheets()[0] # 通過索引獲取
# Data_sheet = workbook.sheet_by_index(0) # 通過索引獲取
# Data_sheet = workbook.sheet_by_name(u'名稱') # 通過名稱獲取
print(Data_sheet.name) # 獲取sheet名稱
rowNum = Data_sheet.nrows # sheet行數
colNum = Data_sheet.ncols # sheet列數
# 獲取所有單元格的內容
for i in range(rowNum):
for j in range(colNum):
print('{0} '.format(Data_sheet.cell_value(i, j)))
# 獲取整行和整列的值(列表)
rows = Data_sheet.row_values(0) # 獲取第一行內容
cols = Data_sheet.col_values(1) # 獲取第二列內容
print (rows)
print (cols)
# 獲取單元格內容
cell_A1 = Data_sheet.cell(0, 0).value
cell_B1 = Data_sheet.row(0)[1].value # 使用行索引
cell_A2 = Data_sheet.col(0)[1].value # 使用列索引
print(cell_A1, cell_B1, cell_A2)
# 獲取單元格內容的資料型別
# ctype:0 empty,1 string, 2 number, 3 date, 4 boolean, 5 error
print('cell(0,0)資料型別:', Data_sheet.cell(0, 0).ctype)
# 獲取單元格內容為日期的資料
date_value = xlrd.xldate_as_tuple(Data_sheet.cell_value(1,0),workbook.datemode)
print(type(date_value), date_value)
print('%d:%d:%d' % (date_value[0:3]))
使用xlwt編寫excel檔案
import xlwt
path = './Data/2.xlsx'
# 建立工作簿
workbook = xlwt.Workbook(encoding='utf-8')
#建立文字格式
style = xlwt.XFStyle() # 初始化樣式
font = xlwt.Font() # 為樣式建立字型
font.name = 'Times New Roman'
font.bold = True
font.color_index = 4
font.height = 220
style.font = font
borders = xlwt.Borders()
borders.left = 6
borders.right = 6
borders.top = 6
borders.bottom = 6
style.borders = borders
#!!!如果對一個單元格重複操作,會引發error。所以在開啟時加cell_overwrite_ok=True解決
sheet1 = workbook.add_sheet(u'sheet1',cell_overwrite_ok=True)
#表頭內容
header = [u'甲',u'乙',u'丙',u'丁',u'午',u'己',u'庚',u'辛',u'壬',u'癸']
# 寫入表頭
for i in range(0, len(header)):
sheet1.write(0, i, header[i], style)
sheet1.write(1,0,u'合計',style)
#1,2,3,4表示合併區域是從第2行到第3行,從第4列到第5列,0表示要寫入的單元格內容,style表示單元格樣式
sheet1.write_merge(1,2,3,4,0,style)
# 儲存檔案
workbook.save(path)
xml檔案讀寫
xml的樣例檔案是
<?xml version="1.0" encoding="utf-8"?>
<catalog>
<maxid>4</maxid>
<login username="pytest" passwd='123456'>
<caption>Python</caption>
<item id="4">
<caption>測試</caption>
</item>
</login>
<item id="2">
<caption>Zope</caption>
</item>
</catalog>
讀取xml檔案
import xml.dom.minidom
#開啟xml文件
dom = xml.dom.minidom.parse('./Data/tmp_5.xml')
#得到文件元素物件
root = dom.documentElement
print(root.nodeName)
#節點值,這個屬性只對文字結點有效
print(root.nodeValue)
print(root.nodeType)
print(root.ELEMENT_NODE)
#通過子節點的nodeName查詢結點,由於存在同名子節點,所以返回list型別
item_list = root.getElementsByTagName('item')
item1 = item_list[0]
item2 = item_list[1]
#通過結點的屬性名獲取屬性值
id1 = item1.getAttribute('id')
id2 = item2.getAttribute('id')
print(item1.nodeName,id1)
print(item2.nodeName,id2)
item_list = root.getElementsByTagName('caption')
item1 = item_list[0]
item2 = item_list[1]
#獲取結點的資料
print(item1.firstChild.data)
print(item2.firstChild.data)
寫入xml檔案
import xml.dom.minidom
impl = xml.dom.minidom.getDOMImplementation()
dom = impl.createDocument(None, 'employees', None)
root = dom.documentElement
employee = dom.createElement('employee')
employee.setAttribute('id' ,'1')
root.appendChild(employee)
#建立element結點,結點名為name
nameE=dom.createElement('name')
#建立文字結點,文字結點只有資料,沒有<></>包裹
nameT=dom.createTextNode('linux')
#文字結點作為element結點的第一個子節點
nameE.appendChild(nameT)
employee.appendChild(nameE)
ageE=dom.createElement('age')
ageT=dom.createTextNode('30')
ageE.appendChild(ageT)
employee.appendChild(ageE)
f= open('./Data/tmp_6.xml', 'w', encoding='utf-8')
dom.writexml(f, addindent=' ', newl='\n',encoding='utf-8')
f.close()
輸出檔案結果
<?xml version="1.0" encoding="utf-8"?>
<employees>
<employee id="1">
<name>linux</name>
<age>30</age>
</employee>
</employees>
資料庫資料讀取與儲存
python3目前不支援MySQL,所以我們只能在python2下面執行測試程式。這裡推薦一個教程,有助於掌握MySQL與Python的配合應用——mysql 資料庫