numpy數組之讀寫文件

將 numpy 數組存入文件,有多種文件類型可供選擇,對應地就有不一樣的方法來讀寫。python

下面我將介紹讀寫 numpy 的三類文件:數組

  • txt 或者 csv 文件
  • npy 或者 npz 文件
  • hdf5 文件

經過 numpy 讀寫 txt 或 csv 文件

import numpy as np

a = np.array(range(20)).reshape((4, 5))
print(a)

# 後綴改成 .txt 同樣
filename = 'data/a.csv'
# 寫文件
np.savetxt(filename, a, fmt='%d', delimiter=',')

# 讀文件
b = np.loadtxt(filename, dtype=np.int32, delimiter=',')
print(b)

缺點:性能優化

  • 只能保存一維和二維 numpy 數組,當 numpy 數組 a 有多維時,須要將其 a.reshape((a.shape[0], -1)) 後才能用這種方式保存。
  • 不能追加保存,即每次 np.savetxt() 都會覆蓋以前的內容。

經過 numpy 讀寫 npy 或 npz 文件

讀寫 npy 文件

import numpy as np

a = np.array(range(20)).reshape((2, 2, 5))
print(a)

filename = 'data/a.npy'
# 寫文件
np.save(filename, a)

# 讀文件
b = np.load(filename)
print(b)
print(b.shape)

優勢:性能

  • npy 文件能夠保存任意維度的 numpy 數組,不限於一維和二維;
  • npy 保存了 numpy 數組的結構,保存的時候是什麼 shape 和 dtype,取出來時就是什麼樣的 shape 和 dtype。

缺點:優化

  • 只能保存一個 numpy 數組,每次保存會覆蓋掉以前文件中存在的內容(若是有的話)。

讀寫 npz 文件

import numpy as np

a = np.array(range(20)).reshape((2, 2, 5))
b = np.array(range(20, 44)).reshape(2, 3 ,4)
print('a:\n', a)
print('b:\n', b)

filename = 'data/a.npz'
# 寫文件, 若是不指定key,那麼默認key爲'arr_0'、'arr_1',一直排下去。
np.savez(filename, a, b=b)

# 讀文件
c = np.load(filename)
print('keys of NpzFile c:\n', c.keys())
print("c['arr_0']:\n", c['arr_0'])
print("c['b']:\n", c['b'])

優勢:code

  • npy 文件能夠保存任意維度的 numpy 數組,不限於一維和二維;
  • npy 保存了 numpy 數組的結構,保存的時候是什麼 shape 和 dtype,取出來時就是什麼樣的 shape 和 dtype;
  • 能夠同時保存多個 numpy 數組;
  • 能夠指定保存 numpy 數組的 key,讀取的時候很方便,不會混亂。

缺點:htm

  • 保存多個 numpy 數組時,只能同時保存,即 np.savez(filename, a, b=b)。每次保存會覆蓋掉以前文件中存在的內容(若是有的話)。

經過 h5py 讀寫 hdf5 文件

優勢:blog

  • 不限 numpy 數組維度,能夠保持 numpy 數組結構和數據類型;
  • 適合 numpy 數組很大的狀況,文件佔用空間小;
  • 能夠經過 key 來訪問 dataset(能夠理解爲 numpy.array),讀取的時候很方便,不會混亂。
  • 能夠不覆蓋原文件中含有的內容。

簡單讀取

import numpy as np
import h5py

a = np.array(range(20)).reshape((2, 2, 5))
b = np.array(range(20)).reshape((1, 4, 5))
print(a)
print(b)

filename = 'data/data.h5'
# 寫文件
h5f = h5py.File(filename, 'w')
h5f.create_dataset('a', data=a)
h5f.create_dataset('b', data=b)
h5f.close()

# 讀文件
h5f = h5py.File(filename, 'r')
print(type(h5f))
# 經過切片獲得numpy數組
print(h5f['a'][:])
print(h5f['b'][:])
h5f.close()

經過切片賦值

import numpy as np
import h5py

a = np.array(range(20)).reshape((2, 2, 5))
print(a)

filename = 'data/a.h5'
# 寫文件
h5f = h5py.File(filename, 'w')
# 當數組a太大,須要切片進行操做時,能夠不直接對h5f['a']進行初始化;
# 當以後不須要改變h5f['a']的shape時,能夠省略maxshape參數
h5f.create_dataset('a', shape=(2, 2, 5), maxshape=(None, 2, 5), dtype=np.int32, compression='gzip')
for i in range(2):
    # 採用切片的形式賦值
    h5f['a'][i] = a[i]
h5f.close()

# 讀文件
h5f = h5py.File(filename, 'r')
print(type(h5f))
print(h5f['a'])
# 經過切片獲得numpy數組
print(h5f['a'][:])

同一個 hdf5 文件能夠建立多個 dataset,讀取的時候按照 key 來便可。索引

總結

  • csv 和 txt 只能用來存一維或二維 numpy 數組;
  • npy 用來存單個 numpy 數組,npz 能夠同時存多個 numpy 數組,二者都不限 numpy 維度,且都保持 numpy 數組的 shape 和 dtype,寫文件時若原文件存在只能覆蓋原文件內容;
  • 當 numpy 數組很大時,最好使用 hdf5 文件,hdf5 文件相對更小;
  • 當 numpy 數組很大時,對整個 numpy 數組進行運算容易發生 MemoryError,那麼此時能夠選擇對 numpy 數組切片,將運算後的數組保存到 hdf5 文件中,hdf5 文件支持切片索引。

References

當Python趕上HDF5--性能優化實戰 -- 張玉騰
雜: PYTHON上數據儲存:推薦h5py -- Pony_s

相關文章
相關標籤/搜索