pickle(模型存儲取出)

在機器學習中,我們常常需要把訓練好的模型存儲起來,這樣在進行決策時直接將模型讀出,而不需要重新訓練模型,這樣就大大節約了時間。Python提供的pickle模塊就很好地解決了這個問題,它可以序列化對象並保存到磁盤中,並在需要的時候讀取出來,任何對象都可以執行序列化操作。

5種協議

  • Protocol version 0 是最原始一種協議,它向後與以前的Python版本兼容。
  • Protocol version 1 是一種老的二進制格式,它也兼容以前版本的Python。
  • Protocol version 2 是在 Python2.3 中被引入的。它提供了對新類型new-style class更加高效的pickling。
  • Protocol version 3 是在 Python3.0 中加入的。它明確的支持了字節對象bytes objects的pickling,且不能被Python2.x unpickling。這個協議就是默認的協議,也是在Python3的其他版本中推薦的協議。
  • Protocol version 4 是在Python3.4中被加入的。它增加了對超大對象的支持,且支持pickling的對象類型也更多。

Pickle模塊常用的接口函數

  1. pickle.HIGHEST_PROTOCOL
    這是一個整數,表示最高可用的協議版本。這個值可以作爲參數protocol傳給函數dump()和dumps()以及Pickler構造器。
  2. pickle.DEFAULT_PROTOCOL
    這是一個整數,表示用來pickling的默認協議版本。可能比3. 3. pickle.HIGHEST_PROTOCOL小。目前默認的協議版本是3,協議3是專門爲Python3設計的一種新的協議。
  3. pickle.dump(obj, file, protocol=None, *, fix_imports=True)
    pickle.dump(obj, file, [,protocol])
    將一個對象序列化,並將其寫入文件對象中。這等價於函數Pickler(file, protocol).dump(obj)。
  4. protocol參數是可選的,是一個整數,用來表示用到的協議版本。支持的協議爲0到HIGHEST_PROTOCOL。如果沒有指定,就是默認的DEFAULT_PROTOCOL。如果傳入的是負數,那麼HIGHEST_PROTOCOL就被指定爲協議版本。
    file參數必須有一個write()方法,該方法接收一個單字節參數。
  5. pickle.dumps(obj, protocol=None, *, fix_imports=True)
    返回一個序列化後的對象,作爲字節對象bytes objects,而不是將其寫入文件中。
    pickle.dumps(obj[, protocol])
  • 函數的功能:將obj對象序列化爲string形式,而不是存入文件中。
  • obj:想要序列化的obj對象。
  • protocal:如果該項省略,則默認爲0。如果爲負值或HIGHEST_PROTOCOL,則使用最高的協議版本。
  1. pickle.load(file, *, fix_imports=True, encoding=“ASCII”, errors=“strict”)
    pickle.load(file)
    從文件對象中讀取一個序列化後的對象並將其解序列化成原來的層級結構。這等價於函數Unpickler(file).load()。
    file參數必須有兩個方法:read()方法接收一個整數參數和一個readlines()方法不要求參數。兩個方法都應該返回字節。
  2. pickle.loads(bytes_object, *, fix_imports=True, encoding=“ASCII”, errors=“strict”)
    pickle.loads(string)
    — 函數的功能:從string中讀出序列化前的obj對象。
    從字節對象bytes objects讀取一個被序列化的對象,返回解序列化後的對象。

pickle模塊衍生出兩個類

  1. class pickle.Pickler(file, protocol=None, *, fix_imports=True)
  2. class pickle.Unpickler(file, *, fix_imports=True, encoding=“ASCII”, errors=“strict”)
    這兩個類也有一些方法,跟上面的方法等價,例如Pickler類的dump()方法、Unpickler類的load()方法。

什麼東西可以被序列化

None, True, 和 False
整數、浮點數和複數
字符串、字節和字節數組
元組、列表、集合和僅包括可序列化對象的字典
定義在一個模塊上層的函數
定義在一個模塊上層的內建函數
定義在一個模塊上層的類
一些類的實例,這些類包括其__dict__或調用__getstate__()的結果是可序列化的。

JSON和pickle模塊的區別

1、JSON只能處理基本數據類型。pickle能處理所有Python的數據類型。
2、JSON用於各種語言之間的字符轉換。pickle用於Python程序對象的持久化或者Python程序間對象網絡傳輸,但不同版本的Python序列化可能還有差異。

import pickle

#支持序列化的字典
data = {
    'a': [1, 2.0, 3, 4+6j],
    'b': ("character string", b"byte string"),
    'c': {None, True, False}
}

with open('data.pickle', 'wb') as f:
    # Pickle the 'data' dictionary using the highest protocol available.
    # 用最高協議版本序列化data字典,將其寫入文件"data.pickle"中
    pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)


# 經過上面的代碼,已經在本地磁盤中寫入了一個文件"data.pickle",現在我們將其讀入,並將其解序列化
import pickle

with open('data.pickle', 'rb') as f:
    # The protocol version used is detected automatically, so we do not
    # have to specify it.
    data = pickle.load(f)
print(data)

以上一段代碼的輸出內容如下,可見經過解序列化之後的結構與原來的結構保持一致
{'a': [1, 2.0, 3, (4+6j)], 'b': ('character string', b'byte string'), 'c': {False, None, True}}

【注】 dump() 與 load() 相比 dumps() 和 loads() 還有另一種能力:dump()函數能一個接着一個地將幾個對象序列化存儲到同一個文件中,隨後調用load()來以同樣的順序反序列化讀出這些對象。

 【代碼示例】
import pickle  
dataList = [[1, 1, 'yes'],  
            [1, 1, 'yes'],  
            [1, 0, 'no'],  
            [0, 1, 'no'],  
            [0, 1, 'no']]  
dataDic = { 0: [1, 2, 3, 4],  
            1: ('a', 'b'),  
            2: {'c':'yes','d':'no'}}  
  
#使用dump()將數據序列化到文件中  
fw = open('dataFile.txt','wb')  
# Pickle the list using the highest protocol available.  
pickle.dump(dataList, fw, -1)  
# Pickle dictionary using protocol 0.  
pickle.dump(dataDic, fw)  
fw.close()  
  
#使用load()將數據從文件中序列化讀出  
fr = open('dataFile.txt','rb')  
data1 = pickle.load(fr)  
print(data1)  
data2 = pickle.load(fr)  
print(data2)  
fr.close()  
  
#使用dumps()和loads()舉例  
p = pickle.dumps(dataList)  
print( pickle.loads(p) )  
p = pickle.dumps(dataDic)  
print( pickle.loads(p) )  

結果爲:
[[1, 1, ‘yes’], [1, 1, ‘yes’], [1, 0, ‘no’], [0, 1, ‘no’], [0, 1, ‘no’]]
{0: [1, 2, 3, 4], 1: (‘a’, ‘b’), 2: {‘c’: ‘yes’, ‘d’: ‘no’}}
[[1, 1, ‘yes’], [1, 1, ‘yes’], [1, 0, ‘no’], [0, 1, ‘no’], [0, 1, ‘no’]]
{0: [1, 2, 3, 4], 1: (‘a’, ‘b’), 2: {‘c’: ‘yes’, ‘d’: ‘no’}}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章