Python學習日誌-csv、json、xlsx、pickle、其它二進位檔案的讀寫

Kayden
13 min readDec 26, 2020

--

前言

內文為自行查看書籍、查閱網路資訊後,進行整理幫助自我理解的學習日誌,並無商業行為,內容大多轉載於書籍以及他人的分享,來源皆附於文章下方的參考資料。此外內容表達的為自我的理解與解釋,並不保證一定正確,請僅以參考視之,若有錯誤歡迎告知。

讀寫 csv 檔

一般都是使用pandas進行操作,pd.read_csv() 讀成 DataFrame 格式的檔案物件 ,檔案內容的操作,就以 DataFrame 格式的操作方式進行操作,最後df.to_csv() 匯出。

csv 檔

例子中不含中文的csv檔為 google play store上 app 統計的資料,可於網路上找尋到公開檔案。

import pandas as pd# 對含中文的csv進行讀取與匯出
df = pd.read_csv('含中文csv.csv', encoding='utf-8') # 讀取
print(df)
type(df) # 為 DataFrame 格式
df['公司簡稱'].tolist() # 以 DataFrame 型別進行操作
df.to_csv('test_df.csv', encoding='utf-8-sig') # 匯出
# 使用 utf-8 仍跑出亂碼,使用 utf-8-sig 可解決
# 對不含中文的csv進行讀取與匯出
df2 = pd.read_csv('googleplaystore.csv')
print(df2.head())
df2.to_csv('test_df2.csv')

讀寫 xlsx 檔

  • 用pandas進行excel讀寫
  • 用openpyxl進行excel讀寫 (only xlsx檔)

用pandas進行excel讀寫

與讀取csv檔相似,pd.read_excel() 讀成 DataFrame 格式的檔案物件 ,檔案內容的操作,就以 DataFrame 格式的操作方式進行操作,最後df.to_excel() 匯出。

xlsx 檔
# 使用 pandas 讀取 xlsx
import pandas as pd
df = pd.read_excel('上市公司資料.xlsx') # 讀取
type(df) # 為 DataFrame 格式
df.to_excel('test_df.xlsx') # 匯出

用openpyxl進行excel讀寫 (only xlsx檔)

# 使用 openpyxl 像excel工作表一樣
import openpyxl
# 讀取後為workbook 物件
workbook = openpyxl.load_workbook('上市公司資料.xlsx')
# worksheet 物件
worksheet = workbook.get_sheet_by_name('Sheet1')
# 得到第3行的資料
row3 = [item.value for item in list(worksheet.rows)[2]]
# 得到第3欄的資料
col3 = [item.value for item in list(worksheet.columns)[2]]
# 得到第2行第3欄的資料
cell_2_3 = worksheet.cell(row=2, column=3).value
# 用欄行位置得到資料
worksheet.cell(row=1, column=3).value
# 用 cell 得到資料
worksheet['C1'].value

worksheet['C1'] = 'HA' # 改寫資料
worksheet['C1'].value
workbook.save('new.xlsx') # 匯出

讀寫 json 檔

當要與其它程式進行溝通時,常常會使用到的共通格式→Json
Json :JavaScript Object Notation (JavaScript 物件表示法) → 輕鬆的表示物件

以下說明是JavaScript的語法:
Var point = {} 建構物件(point)
大括號{}內放成員、屬性
範例:’{“成員名稱” : 成員年紀, “Tom”:3, “May”:4}’

從範例可以感覺得出來,json 的格式形態長的跟 Python 裡的 dict 型別很像。因此可以利用 json 套件,原始的 json 格式的資料解析成 dict/list 的表示形式。

json套件裡常用到的4種方法(之間的比較可以參考該文章):

範例:json 的讀取與寫入

import json # 匯入 json 套件dic = {'成員名稱':'成員年齡',
'Tom':3,
'May':4}
json_form = json.dumps(dic)
type(dic) # dict
type(json_form) # str
# 創造一個 josn 檔,寫入並讀取
with open('try json.json', mode='a+') as f:
json.dump(dic, f) # 將dict轉為str,並寫入json檔案中
f.seek(0)
data = json.load(f) # 從json檔案中讀取資料
print(data)

讀寫 pickle 檔

模組 pickle,pickle 它跟 Json 相似,都是用來壓縮資料、保存、並可隨時隨地解開我們儲存好的資料,還原我們 python 的工作階段。不過 pickle 是專於 python 中使用,只是純 python 的專案,不像 Json 可以跨語言使用。

簡單比較 pickle 與 Json:

Json vs Pickle

於安全性上,若 pickle 有人惡意建構,將在解封 (unpickling) 時執行惡意的代碼,故只可對信任來源的數據進行 unpickling,而 Json 對於不信任的 Json 檔並不會於解封時執行代碼。這樣看來 pickle 差勁的很,到底為什麼沒有被淘汰呢? 因為 pickle 是專門為 python 設計的,它的優點在於它可以儲存 python 的工作階段,儲存 python 中的變數,就算此變數物件化了仍可以儲存,而此點是 Json 無法做到的,Json 只能支援部分型別的資料。此外,pickle 可以將多個對象(變數)存入一個 .pkl 檔案中,而 Json 無法。

pickle 四大函式 ( dumps, dump, loads, load )

最常使用的為 dump, load 兩函式
● dump: 將 obj 物件序列化存入已經開啟的 file 中。
pickle.dump(obj, file, protocol=None) # protocol:序列化使用的協議
● load: 從已打開的 file 文件中讀取 pickling 的對象,重見其中特定對象的層次結構並返回,亦即讀取 pickle 檔案物件。

【例子1】寫入單一變數資料

import pickle# 【變數資料為 dict 型別】
my_dict = {
'a': 1,
'b': 2,
'c': 3,
}
# 變數資料儲存為 pickle 檔
with open('test.pickle', 'wb') as f: # pickle 是二進位格式
pickle.dump(my_dict, f)
# 讀取 pickle 資料
with open('test.pickle', 'rb') as f: # pickle 是二進位格式
new_dict = pickle.load(f)

print(new_dict)
# 【變數資料為 object】
class dog:
def __init__(self, color):
self.color = color

puppy = dog('black')

# 變數資料儲存為 pickle 檔
with open('test.pickle', 'wb') as f:
pickle.dump(puppy, f)
# 讀取 pickle 資料
with open('test.pickle', 'rb') as f:
my_dog = pickle.load(f)

print(my_dog.color)

【例子2】寫入多個變數資料
常常要對整個資料集進行多步處理,保存一些必要的資料,單使用 pandas 的DataFrame 結構無法方便的進行保存,因此使用 pickle 資料格式對所有物件進行序列化保存。

# 寫入dataset.pickle文件
with open('dataset.pickle', 'wb') as f:
# dataframe 型別
pickle.dump(train_set, f, pickle.HIGHEST_PROTOCOL)
# dataframe 型別
pickle.dump(test_set, f, pickle.HIGHEST_PROTOCOL)
# list 型別
pickle.dump(cate_list, f, pickle.HIGHEST_PROTOCOL)
# tuple 型別
pickle.dump((user_count, item_count, cate_count, max_sl), f, pickle.HIGHEST_PROTOCOL)
# 讀取
with open('dataset.pickle', 'rb') as f:
train_set = np.array(pickle.load(f))
test_set = pickle.load(f)
cate_list = pickle.load(f)
user_count, item_count, cate_count, max_sl = pickle.load(f)

● dumps: 將 obj 序列化後的結果做為 bytes型別直接返回,並不將之寫入文件中。
pickle.dumps(obj, protocol=None)
● loads: data為bytes型別,從bytes型別中讀出序列化前的 obj 物件。
pickle.loads(data)

可以被 Pickling/Unpickling 的物件

下列類型可以實現:
• None、True 和 False
• 整數、浮點數、複數
• str、byte、bytearray
• 只包含可封存物件的集合,包括 tuple、list、set 和 dict
• 定義在模組最外層的函數(使用 def 定義,lambda 函數則不可以)
• 定義在模組最外層的內置函數
• 定義在模組最外層的類

讀寫 .npy / .npz 檔

npy / npz 格式為 Numpy 的二進位儲存格式,亦即將陣列以二進位格式儲存到磁碟裡。

【.npy】儲存一個陣列變數資料
np.load: 讀取
np.save: 儲存

import numpy as np
a = np.arange(5)
np.save('test.npy', a) # 儲存一個陣列變數資料
a = np.load('test.npy') # 讀取 .npy
print(a)

【.npz】儲存多個陣列變數資料
np.savez(‘filename’, var1, var2,….): 儲存
第一引數為檔名,其餘引數為需要儲存的陣列變數名稱,也可以使用關鍵字引數對該陣列變數取名字,而沒使用關鍵字引數命名的陣列變數,則會自動起名為 arr_0, arr_1,…。

import numpy as np
a = np.arange(10)
b = np.arange(50)
c = np.arange(0,50,2)
np.savez('array_save.npz', a, b, c_array=c) # 儲存多個陣列變數資料
import numpy as np
A=np.load('array_save.npz') # 讀取 .npz,返回類似 dict 的物件
print(A['arr_0'])
print(A['arr_1'])
print(A['c_array'])

HDF5 格式

HDF5,階層結構的大規模資料儲存格式,可讓我們方便且快速的存取巨大的檔案,不受限於記憶體及避免讀取巨大檔案的緩慢問題,亦即提供方便的存取及計算,且可支援其它OS的讀取,開放且免費。HDF5 常用在大數據的資料儲存,像是利用影像分析進行電腦視覺、機器學習、深度學習相關專案中,相較於 csv 可以更快速的讀寫。

每個 HDF5 檔案本身自成一個檔案系統,內部以階層式來存放各種形態的資料。一個HDF5文件是一種存放兩類對象的容器:dataset和group. Dataset是類似於數組的數據集,而group是類似文件夾一樣的容器,存放dataset和其他group。在使用h5py的時候需要牢記一句話:groups類比詞典,dataset類比Numpy中的數組。

import h5py  #導入工具包  
import numpy as np
#HDF5的寫入:
imgData = np.zeros((30,3,128,256))
f = h5py.File(‘HDF5_FILE.h5‘,‘w‘) #創建一個h5文件,文件指針是f
f[‘data‘] = imgData #將數據寫入文件的主鍵data下面
f[‘labels‘] = range(100) #將數據寫入文件的主鍵labels下面
f.close() #關閉文件

#HDF5的讀取:
f = h5py.File(‘HDF5_FILE.h5‘,‘r‘) #打開h5文件
f.keys() #可以查看所有的主鍵
a = f[‘data‘][:] #取出主鍵為data的所有的鍵值
f.close()

參考資料:

● Python資料運算與分析實戰 一次搞懂Numpy、Scipy、Matplotlib、pandas(書籍作者:中久喜 健司)
Python Json模組中dumps、loads、dump、load函式介紹
python 檔案讀寫(作者:CW Lin)
Python|讀、寫Excel文件(三種模塊三種方式)
Python序列化 — -Pickle模块【大量数据的情况下,如何提高Python读写数据的速度?
使用 Pickle 模組保存 Python 資料
python說明文件-pickle
Python資料儲存:pickle模組的使用
numpy的檔案儲存.npy .npz 檔案詳解
巨量資料的好夥伴HDF5 & REDIS
h5py 簡單操作 動態調整 dataset 大小
【Python系列】HDF5文件介紹
詳解如何在python中讀寫和儲存matlab的資料檔案(*.mat)
Python笔记 — — 读写mat数据

--

--