python3存儲numpy格式的矩陣


技術背景

numpy在python中的地位是相當高的,即使是入門的python使用者也會經常看到這個庫的使用。除了替代python自帶的列表數據格式list之外,numpy的一大優勢是其底層的高性能實現方式,比如前一篇博客中所提到的矢量運算,就是一種基於SIMD的底層運算優化方案,使得numpy的計算速度遠高於一個普通的for循環。

而在日常運算的過程中,有些數據往往是不會變化的,比如機器學習中的測試和訓練數據。那么如果這里使用的是numpy的數據結構的話,就會涉及到相關數據的存儲,numpy可以將其數據存儲為.npy或者.npz結構。

npy結構的數據存儲

npy格式適用於單個numpy列表的存儲,這個列表的維度可以是任意的,但是最外層必須是一個numpy的列表結構。以下用ipython來展示npy文件的基本使用方法,首先是創建一個數組,然后用np.save保存到一個給定的文件名中:

[dechin@dechin-manjaro numpy]$ ipython
Python 3.8.5 (default, Sep  4 2020, 07:30:14) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.19.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import numpy as np

In [2]: test_arr = np.arange(10)

In [3]: np.save('test_arr', test_arr)

In [5]: !ls -l
總用量 4
-rw-r--r-- 1 dechin dechin 208  5月  2 18:52 test_arr.npy

可以看到文件名會自動補充npy的后綴,然后可以在當前目錄下使用np.load函數直接加載剛才保存的數據:

In [6]: print (np.load('test_arr.npy'))
[0 1 2 3 4 5 6 7 8 9]

類似的可以測試一下多個維度的隨機數組:

In [7]: test_arr = np.random.randn(2,5)

In [8]: np.save('random_arr', test_arr)

In [9]: !ls -l
總用量 8
-rw-r--r-- 1 dechin dechin 208  5月  2 18:56 random_arr.npy
-rw-r--r-- 1 dechin dechin 208  5月  2 18:52 test_arr.npy

In [10]: print (np.load('random_arr.npy'))
[[ 2.6917403   0.01488535 -0.5259401  -1.41512577  0.65968369]
 [-0.68929493  0.30153131  0.84906878 -2.20849715  0.34260589]]

除了可以保存numpy格式的數組,還可以直接保存python本身的數組格式的數據:

In [11]: normal_arr = [1,3,5,7,9]

In [12]: np.save('normal_arr', normal_arr)

In [13]: print (np.load('normal_arr.npy'))
[1 3 5 7 9]

甚至還可以保存一些非列表格式的數據,比如python中的tuple,但是保存后重新加載的數據格式,會被自動轉化成列表格式:

In [14]: tuple_arr = [(1,2),(2,3),(3,4)]

In [15]: np.save('tuple_arr', tuple_arr)

In [16]: print (np.load('tuple_arr.npy'))
[[1 2]
 [2 3]
 [3 4]]

npz結構的數據存儲

上面介紹的npy數據結構存儲下來是一個二進制的文件,僅用於單個列表數據結構的存儲,這里的npz數據結構可以存儲多個列表結構的對象,可以直接參考一個使用案例:

In [17]: multi_arr1 = 3

In [18]: multi_arr2 = [1,2,3]

In [19]: multi_arr3 = (4,5)

In [20]: multi_arr4 = [[6,7],[8,9]]

In [22]: np.savez('multi_arr',multi_arr1,multi_arr2,multi_arr3,named_arr=multi_arr4)

In [23]: !ls -l
總用量 20
-rw-r--r-- 1 dechin dechin 1078  5月  2 19:09 multi_arr.npz
-rw-r--r-- 1 dechin dechin  168  5月  2 19:00 normal_arr.npy
-rw-r--r-- 1 dechin dechin  208  5月  2 18:56 random_arr.npy
-rw-r--r-- 1 dechin dechin  208  5月  2 18:52 test_arr.npy
-rw-r--r-- 1 dechin dechin  176  5月  2 19:02 tuple_arr.npy

In [24]: data=np.load('multi_arr.npz')

In [25]: data['arr_0']
Out[25]: array(3)

In [26]: data['arr_1']
Out[26]: array([1, 2, 3])

In [27]: data['arr_2']
Out[27]: array([4, 5])

In [28]: data['named_arr']
Out[28]: 
array([[6, 7],
       [8, 9]])

npz的數據結構中,除了列表以外的格式都會被自動轉化成numpy的列表。而多個的列表對象最終是以字典的形式存儲在文件中,如果不加以定義,那么索引的名稱默認為arr_加上一個數字的格式,以0為起點。如果需要手動的命名,需要在傳入savez函數的末尾處加上手動命名的對象,比如上面實例中的named_arrnpz文件的讀取方式跟npy是一樣的,使用np.load函數即可。

存儲數據的壓縮

最后我們再額外介紹一個tar壓縮包的使用方法,如果存儲的npz文件較大,可以通過tar -zcvf filename.tar.gz filename.npz打包成一個壓縮包,特別是當數據中0的數量較多時,可以獲得一個非常理想的壓縮比。

[dechin@dechin-manjaro numpy]$ ll
總用量 20
-rw-r--r-- 1 dechin dechin 1078  5月  2 19:09 multi_arr.npz
-rw-r--r-- 1 dechin dechin  168  5月  2 19:00 normal_arr.npy
-rw-r--r-- 1 dechin dechin  208  5月  2 18:56 random_arr.npy
-rw-r--r-- 1 dechin dechin  208  5月  2 18:52 test_arr.npy
-rw-r--r-- 1 dechin dechin  176  5月  2 19:02 tuple_arr.npy
[dechin@dechin-manjaro numpy]$ tar -zcvf multi_arr.tar.gz multi_arr.npz 
multi_arr.npz
[dechin@dechin-manjaro numpy]$ ll
總用量 24
-rw-r--r-- 1 dechin dechin 1078  5月  2 19:09 multi_arr.npz
-rw-r--r-- 1 dechin dechin  427  5月  2 19:14 multi_arr.tar.gz
-rw-r--r-- 1 dechin dechin  168  5月  2 19:00 normal_arr.npy
-rw-r--r-- 1 dechin dechin  208  5月  2 18:56 random_arr.npy
-rw-r--r-- 1 dechin dechin  208  5月  2 18:52 test_arr.npy
-rw-r--r-- 1 dechin dechin  176  5月  2 19:02 tuple_arr.npy

而關於tar.gz格式的文件的解壓縮,則是使用tar -xvf filename.tar.gz命令。

總結概要

在科學計算中對於恆定不變的數據,不一定需要實時保存在內存中,或者是需要跨平台運算的數據,我們可以將其保存為numpy格式的列表文件npy或者npz。而如果存儲的文件過大,本文也額外介紹了簡單的tar壓縮與解壓縮的使用方法。

版權聲明

本文首發鏈接為:https://www.cnblogs.com/dechinphy/p/npz.html
作者ID:DechinPhy
更多原著文章請參考:https://www.cnblogs.com/dechinphy/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM