python读取序列5之后的数据_Python 基本功: 5. 数据序列化
這篇文章緊接著前篇:多多教Python:Python 基本功: 4. 讀寫文件?zhuanlan.zhihu.com
仔細閱讀的小伙伴會發現,在基本功4 里最后的一個示例中,我們讀取解析了文件中的內容,并且把其中的日期,價格金融數據存入了 Python 字典當中:
In[4] abc_dict
Out[4]:{datetime.datetime(2019, 7, 18, 0, 0): 9682.24,
datetime.datetime(2019, 7, 17, 0, 0): 9411.61,
datetime.datetime(2019, 7, 16, 0, 0): 10858.7,
datetime.datetime(2019, 7, 15, 0, 0): 10195.0,
datetime.datetime(2019, 7, 14, 0, 0): 11378.23,
datetime.datetime(2019, 7, 13, 0, 0): 11810.0,
datetime.datetime(2019, 7, 12, 0, 0): 11338.9,
datetime.datetime(2019, 7, 11, 0, 0): 12090.99,
datetime.datetime(2019, 7, 10, 0, 0): 12577.85}
我們知道了如何從文章讀取數據,解析,保存 (原數據),但是我們該如何保存 abc_dict 這個字典呢?這篇文章通過對數據的序列化,和其更高層次的應用,來了解我們如何正確的對 Python 數據類做存儲。
教程需求:Mac OS (Windows, Linux 會略有不同)
安裝了 Python 3.0 版本以上, Anaconda
數據序列化
首先我們來了解一下什么是數據序列化。序列化 (Serialization),是指把程序中的一個類轉化成一個標準化的格式。標準化的意義是這個格式可以跨程序,跨平臺的被使用,而且保持其原有的內容,規范。
首先我們舉個例子,在不用數據序列化的方法,而是直接把字典 abc_dict 存入文件,則是下面的情況:
In [1]:save_file = "abc_dict.txt"
In [2]:with open(save_file, 'w') as file_to_write:
file_to_write.write(str(abc_dict))創建一個變量,定義要存入文件名稱。
首先把字典轉化成 Python 基礎字符串,因為字典本身不能直接被寫入文件,然后再把字符串寫入文件中。
運行之后,我們會在本地找到一個新的文件,如果你打開的話就是這樣:abc_dict.txt
我們來專業的分析一下這么做的幾個問題:一致性:保存在文件的是一個字符串,當你再次讀取的時候,你需要再次做文件解析,并且沒有任何保證解析出來的和保存的內容是一樣的。
有效性:數據非常冗長,原本日期 7/18/2019 變成了 datetime.datetime(2019, 7, 18, 0, 0) 這么一個字符串。在跨平臺使用時,占用了過多的內存和網絡資源。
兼容性:文件是 .txt 格式,沒有一個標準來定義該如何讀取里面的內容。雖然在寫入的時候是 Python 字典轉化的,但是讀取的程序如果不是 Python,或者不存入字典,就會出現 兼容性問題。
保持數據傳輸的 一致性,有效性,兼容性 就是數據序列化的意義,下面介紹在數據流 (Data Flow)中,兩個數據序列化的應用:你的程序需要和其他程序交流,例如 平臺 API, 網頁請求串行任務流,每一個任務結束之后數據通過序列化傳遞到下一個任務。
JSON 序列化
這里我們來介紹第一個序列化方式:JSON。JSON 是一個文件格式,也是一個標準化的數據傳輸方案,通常網站的后端和前段的交流,移動 APP 和云服務器的交流方式都是通過 JSON。所以我們先來看這個比較通用流行的方法:
In [1]:import json
In [2]:simple_dict = {'ticker': 'baba', 'price': '120.5'}
In [3]:with open('simple_dict.txt', 'w') as file_to_write:
json.dump(simple_dict, file_to_write)第一行調用了 Json 模塊 (模塊是較小的庫,可以理解為子庫),Json 不是一個 Python 自帶的基本類型,所以需要調用,但是默認都已經裝好了。
創建一個簡單字典。
用同樣的方法 With 語境,創建一個 simple_dict.txt 文件來保存數據,然后通過調用 json.dump() 方法,把字典轉化成 Json 格式的字符串,然后寫進文件。
現在我們打開 simple_dict.txt 的文件,就可以看到里面的數據是通過 Json 格式保存。你可以建立一個更加復雜的字典來更加明了的發現 Json 格式轉化后的區別:
In [1]: complex_dict = {'ticker': ['baba', 'pdd'], 'price': {'open': 120, 'close': 123, 'vwap': 122}}
然后用同樣的方法保存,打開保存的文件,復制里面的內容,然后進入:Json Parser Online?json.parser.online.fr
一個 Json 在線解析網站,黏貼 Json 內容,就會發現解析過后的字符串顯示的非常清晰。
從 Python 中讀取我們保存下來的 simple_dict 很簡單,只需要一行代碼:
In [1]:with open('simple_dict.txt', 'r') as file_to_read:
loaded_simple_dict = json.load(file_to_read)
print(type(loaded_simple_dict))
Out [1]: json.load() 是直接從文件中讀取全部字符串,然后轉化成 Json 理解的格式,然后傳給變量 loaded simple dict。看了一下這個變量,的確是字典類。
那 Json 方法有什么弊端呢?嘗試把之前創建的 abc_dict 這個字典用同樣的方法保存進文件中,你們會發現 Python 會報錯:
這個錯是因為 abc_dict 字典里的 鑰匙是 Python 的 Datetime 數據類,而 Json 的標準化里面并沒有 Python 的 Datetime 規則,也就是說當遇到一些 Python 特定的高級數據類型的時候,Json 會因為沒有標準而無法進行序列化,而接下來介紹的這個工具會解決這個問題。
Pickle 序列化
Pickle 和 Json 不同的是,Pickle 是 Python 專屬的序列化方案,可以轉化大多數 Python 的數據類型,并且儲存方式是二進制(Byte Code)。二進制的儲存方式只有機器才能理解,但是同時也保證了一定的數據隱秘性和高效性。
下面我們來看如何用 Pickle 來實現數據序列化:
In [1]:import pickle
In [2]:with open('abc.pk', 'wb') as file_to_write:
pickle.dump(abc_dict, file_to_write)
In [3]:with open('abc.pk', 'rb') as file_to_read:
abc_dict_pk = pickle.load(file_to_read)
print(type(abc_dict_pk))
Out [3]:調用 Pickle 模塊。
這里打開文件的方式是 'wb', 因為 pickle 寫入的是二進制格式,如果不加上 'b' 的話會導致無法寫入文件。
寫入文件之后,再用 pickle 讀出數據,同樣的因為讀取的是二進制,我們用了 'rb' 模式。然后我們檢查返回的數據是否是字典類。
我們會發現 Pickle 的語法和 Json 非常相似,雖然本身兩者對數據序列化的處理方式皆然不同,但是得益于 Python 的高級接口抽象(Interface Abstraction),記得 鴨子類型:
我們并不關心對象是什么類型,到底是不是鴨子,只關心行為。
這里兩個方法的行為都是在序列化數據,所以在調用方程上感覺完全一樣。但是本質上 Json 寫入文件的是字符串,而 Pickle 則是把數據轉化成了二進制,兩個是完全不同的處理方案。
小結
現在流行的數據序列化方案還有 Protobuf, 一個谷歌開發的快速輕量級方案:protocolbuffers/protobuf?github.com
另一個是結合了Json 和 二進制優勢的 Bson:BSON (Binary JSON) Serialization?bsonspec.org
在一個大數據任務當中,通常需要多任務并行和串行結合運算加快速度。為了防止中間一環失敗而導致整個任務重啟,往往會在中間步驟把數據保存下來,就像下圖:Map Reduce 利用 Transient Data (臨時數據) 來做進度保存
在之后的課程中,Json 和 Pickle 都會頻繁的用到的領域有:大數據處理,消費者數據流。
高并發的科學計算。
建立一個神經網絡。
總結
以上是生活随笔為你收集整理的python读取序列5之后的数据_Python 基本功: 5. 数据序列化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 统计学习:基本常用公式(1)
- 下一篇: Python练习:tkinter(1)