<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          使用pickle模塊序列化數(shù)據(jù),優(yōu)化代碼

          共 6711字,需瀏覽 14分鐘

           ·

          2021-05-26 15:58

          pickle是Python標(biāo)準(zhǔn)庫中的一個(gè)二進(jìn)制序列化和反序列化庫。


          可以以二進(jìn)制的形式將數(shù)據(jù)持久化保存到磁盤文件中。可以將數(shù)據(jù)和代碼分離,提高代碼可讀性和優(yōu)雅度。


          一、pickle模塊介紹



          pickle模塊可以對(duì)多種Python對(duì)象進(jìn)行序列化和反序列化,序列化稱為pickling,反序列化稱為unpickling。


          序列化是將Python對(duì)象轉(zhuǎn)化為二進(jìn)制數(shù)據(jù),可以配合文件操作將序列化結(jié)果保存到文件中(也可以配合數(shù)據(jù)庫操作保存到數(shù)據(jù)庫中)。


          反序列化則是將二進(jìn)制數(shù)據(jù)還原回Python對(duì)象,先從文件中(或數(shù)據(jù)庫中)讀取出保存的二進(jìn)制數(shù)據(jù)。


          pickle模塊常用的方法如下:


          dump(obj, file): 將Python對(duì)象序列化,并將序列化結(jié)果寫入到打開的文件中。


          load(file): 從打開的文件中讀取出保存的數(shù)據(jù),將數(shù)據(jù)反序列化成Python對(duì)象。


          dumps(obj): 將Python對(duì)象序列化,并直接返回序列化的二進(jìn)制數(shù)據(jù)(類型為bytes),而不寫入文件。


          loads(data): 將字節(jié)碼數(shù)據(jù)反序列化成Python對(duì)象,傳入的數(shù)據(jù)必須為二進(jìn)制數(shù)據(jù)(bytes-like object)。


          dump()和load()是互逆的方法,dumps()和loads()是互逆的方法,使用哪一對(duì)方法取決于是否要讀寫文件。


          二、pickle可以序列化哪些Python對(duì)象



          pickle與json相比,json數(shù)據(jù)有嚴(yán)格的格式要求,只能保存滿足格式要求的數(shù)據(jù),而pickle幾乎可以序列化Python中的所有數(shù)據(jù)對(duì)象。


          pickle可以序列化的Python對(duì)象如下:

          • None、True和False


          • 整數(shù)、浮點(diǎn)數(shù)、復(fù)數(shù)


          • str、byte、bytearray


          • 只包含可序列化對(duì)象的集合,包括tuple、list、set和dict


          • 定義在模塊最外層的函數(shù)(使用def定義,lambda函數(shù)不可以)


          • 定義在模塊最外層的內(nèi)置函數(shù)


          • 定義在模塊最外層的類


          • 某些類實(shí)例


          三、案例分享



          之前寫過一篇使用matplotlib繪制柱狀圖的文章,參考:Python matplotlib繪制柱狀圖

          文章里有一個(gè)56行的字典,本文利用pickle模塊來將字典序列化寫入文件中,繪圖時(shí)從文件中讀取數(shù)據(jù)并反序列化,實(shí)現(xiàn)數(shù)據(jù)與代碼的分離。


          1. 將數(shù)據(jù)序列化保存


          創(chuàng)建一個(gè)Python腳本pickling.py,先將56行的字典序列化保存。


          # coding=utf-8
          import pickle

          data = {
              ...  # 文末附完整數(shù)據(jù)獲取方式
          }
          with open('S10.pkl''wb'as pkl_file:
              pickle.dump(data, pkl_file)


          序列化只需要兩行代碼,打開一個(gè)文件對(duì)象,使用dump()方法將字典序列化保存到了S10.pkl文件中,文件默認(rèn)在代碼的同級(jí)目錄下,也可以指定絕對(duì)路徑。注意,打開文件對(duì)象時(shí)使用wb模式。


          S10.pkl的后綴名可以自定義(后綴名不會(huì)改變文件保存的格式),不過因?yàn)槭怯胮ickle模塊序列化的數(shù)據(jù),通常都以.pkl作為后綴,方便識(shí)別。


          直接用IDE打開文件S10.pkl,顯示的內(nèi)容是亂碼的,因?yàn)楸4娴膬?nèi)容是二進(jìn)制數(shù)據(jù)。


          2. 讀取數(shù)據(jù)并反序列化


          # coding=utf-8
          import matplotlib.pyplot as plt
          from matplotlib import ticker
          from numpy import mean
          import pickle


          with open('S10.pkl''rb'as pkl_file:
              data = pickle.load(pkl_file)
          location = ["上單""打野""中單""下路""輔助"]
          win_loc_kill, win_loc_die, win_loc_assists = [[list() for _ in range(5)] for _ in range(3)]
          lose_loc_kill, lose_loc_die, lose_loc_assists = [[list() for _ in range(5)] for _ in range(3)]
          for i in range(5):
              win_loc_kill[i] = [value[0][i][0for value in data.values()]
              win_loc_die[i] = [value[0][i][1for value in data.values()]
              win_loc_assists[i] = [value[0][i][2for value in data.values()]
              lose_loc_kill[i] = [value[1][i][0for value in data.values()]
              lose_loc_die[i] = [value[1][i][1for value in data.values()]
              lose_loc_assists[i] = [value[1][i][2for value in data.values()]
          # noinspection PyTypeChecker
          win_avg_kill = [round(mean(kill), 2for kill in win_loc_kill]
          # noinspection PyTypeChecker
          win_avg_die = [round(mean(die), 2for die in win_loc_die]
          # noinspection PyTypeChecker
          win_avg_assists = [round(mean(assists), 2for assists in win_loc_assists]
          # noinspection PyTypeChecker
          lose_avg_kill = [round(mean(kill), 2for kill in lose_loc_kill]
          # noinspection PyTypeChecker
          lose_avg_die = [round(mean(die), 2for die in lose_loc_die]
          # noinspection PyTypeChecker
          lose_avg_assists = [round(mean(assists), 2for assists in lose_loc_assists]
          fig, axs = plt.subplots(nrows=2, ncols=1, figsize=(2016), dpi=100)
          x = range(len(location))
          axs[0].bar([i-0.2 for i in x], win_avg_kill, width=0.2, color='b')
          axs[0].bar(x, win_avg_die, width=0.2, color='r')
          axs[0].bar([i+0.2 for i in x], win_avg_assists, width=0.2, color='g')
          axs[1].bar([i-0.2 for i in x], lose_avg_kill, width=0.2, color='b')
          axs[1].bar(x, lose_avg_die, width=0.2, color='r')
          axs[1].bar([i+0.2 for i in x], lose_avg_assists, width=0.2, color='g')
          for a, b in zip(x, win_avg_kill):
              axs[0].text(a-0.2, b+0.1'%.02f' % b, ha='center', va='bottom', fontsize=14)
          for a, b in zip(x, win_avg_die):
              axs[0].text(a, b+0.1'%.02f' % b, ha='center', va='bottom', fontsize=14)
          for a, b in zip(x, win_avg_assists):
              axs[0].text(a+0.2, b+0.1'%.02f' % b, ha='center', va='bottom', fontsize=14)
          for a, b in zip(x, lose_avg_kill):
              axs[1].text(a-0.2, b+0.1'%.02f' % b, ha='center', va='bottom', fontsize=14)
          for a, b in zip(x, lose_avg_die):
              axs[1].text(a, b+0.1'%.02f' % b, ha='center', va='bottom', fontsize=14)
          for a, b in zip(x, lose_avg_assists):
              axs[1].text(a+0.2, b+0.1'%.02f' % b, ha='center', va='bottom', fontsize=14)
          for i in range(2):
              axs[i].xaxis.set_major_locator(ticker.FixedLocator(x))
              axs[i].xaxis.set_major_formatter(ticker.FixedFormatter(location))
              axs[i].set_yticks(range(0112))
              axs[i].grid(linestyle="--", alpha=0.5)
              axs[i].legend(['擊殺''死亡''助攻'], loc='upper left', fontsize=16, markerscale=0.5)
              axs[i].set_xlabel("位置", fontsize=18)
              axs[i].set_ylabel("場(chǎng)均數(shù)據(jù)", fontsize=18, rotation=0)
          axs[0].set_title("S10總決賽勝方各位置場(chǎng)均數(shù)據(jù)", fontsize=18)
          axs[1].set_title("S10總決賽負(fù)方各位置場(chǎng)均數(shù)據(jù)", fontsize=18)
          plt.show()


          反序列化代碼也只有兩行,打開文件S10.pkl,然后使用load()方法對(duì)文件對(duì)象反序列化,返回?cái)?shù)據(jù)。開文件對(duì)象時(shí)使用rb模式


          運(yùn)行代碼,繪圖功能正常。



          經(jīng)過pickle模塊的序列化和反序列化,將數(shù)據(jù)持久化到了文件S10.pkl中。實(shí)現(xiàn)了數(shù)據(jù)與代碼的分離,避免了直接在代碼中寫一個(gè)很長(zhǎng)的字典數(shù)據(jù),代碼更加優(yōu)雅。


          在上面的例子中,對(duì)一個(gè)56行的數(shù)據(jù)進(jìn)行序列化,已經(jīng)有不錯(cuò)的效果了。在實(shí)際的項(xiàng)目中,數(shù)據(jù)更大,將數(shù)據(jù)放到代碼中會(huì)占很大的篇幅,進(jìn)行序列化處理的優(yōu)化效果會(huì)更明顯。


          如果有多個(gè)腳本使用同一份數(shù)據(jù),可以直接讀取同一個(gè)序列化數(shù)據(jù)文件,避免了在不同腳本中粘貼同一份數(shù)據(jù)。


          以上就是pickle模塊的序列化介紹,如果需要本文代碼,可以點(diǎn)擊關(guān)注公眾號(hào)“Python碎片”,然后在后臺(tái)回復(fù)“pickle”關(guān)鍵字獲取完整代碼。


          瀏覽 101
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  精品国产AⅤ麻豆 | 精品久久无码 | 日欧 免费视频 | 成人免费在线观看黄片 | 综合亚洲在线 |