python---之table寫hdf5檔案
Python Tables 學習筆記
實在是太煩了,雖然以前也用過python tables來儲存大資料,但是還是有些功能不太懂。我只用了最簡單的create array直接把所有的資料一次性寫入hdf5檔案。但是現在的電腦記憶體比較小,處理的資料太大,一次性寫入,記憶體會不足。另一方面,一邊處理資料,一邊寫入資料,是一種更好的策略。於是自己又重寫學了python tables,也花了不少時間。在此總結下,也為自己做好總結立個標杆。要總結好,不然很快就會忘記了。
- 1
- 2
本文將從tables的讀,寫,以及一些簡單的操作進行簡要描述。使得tables這個tool能夠為我們所用。
首先,我們先介紹下HDF5(Hierarchical Data Format).HDF 是用於儲存和分發科學資料的一種自我描述、多物件檔案格式。HDF 是由美國國家超級計算應用中心(NCSA)建立的,以滿足不同群體的科學家在不同工程專案領域之需要。HDF 可以表示出科學資料儲存和分佈的許多必要條件。其有以下一些特徵:
- 自述性
- 通用性
- 靈活性
- 擴充套件性
- 跨平臺
HDF檔案是安裝樹狀結構組織起來的。其頂部是根節點(),根節點下可以接很多分組(group),每個分組下有可以有很多節點,包括表(table),陣列(array),壓縮陣列(compression array,Earray),可擴充套件壓縮陣列(enlargeable array,Earray),變長陣列(variable length array,VLarray)。每個節點下還有葉子節點,即最終儲存的資料。
簡單知道HDF5檔案的特徵,我們接著介紹下,在python下如何使用tables(其實還有H5Py這個包也是可以用)這個package來實現對HDF5檔案的操作。
假設大家已經把tables及其依賴的庫如numpy等包安裝好在python的環境下。
1 寫資料到表
這裡簡單以pytable裡面的例子進行說明。對於table,我們首先要定義表格中每個元素(field)的資料型別,長度等資訊。如下圖,我們定義了一個particle類,其名稱,資料型別,及長度。比如說name這個field是字串型別,最大長度是16個位元組。
from tables import *
class particle(IsDescription):
'''definition '''
name = StringCol(16) #16-character string
_id = Int64Col() #signed 64-bit interger
energy = Float64Col() #double-precision
- 1
- 2
- 3
- 4
- 5
- 6
- 7
新建一個hdf5檔案,檔名是tutorial.h5, 寫的模式,描述為test file。
f = open_file('tutorial.h5',mode='w',title='test file')
- 1
為了更好地組織資料,我們在根節點下新建一個分組叫detector,描述為Detector information。
group = f.create_group('/','detector','Detector information')
- 1
“/”可以由f.root代替。
接著,我們在detector這個分組下建立一個新的表(table)叫做‘readout’,並初始化為particle形式。
table=f.create_table(group,'readout',particle,'Readout_example')
- 1
接著,我們往表裡新增資料。其中append這個函式用於把資料寫入到I/O buffer中。
for i in range(10):
particle['name']='particle: %6d' %(i)
particle['_id'] = i *(2 **34)
particle['energy'] = float(i *i)
particle.append()
table.flush()
- 1
- 2
- 3
- 4
- 5
- 6
最後還需要呼叫flush函式把資料寫入到硬碟中,並且會釋放被佔用的記憶體,這樣我們就可以處理海量的資料,而不用擔心記憶體不足。
2 從表中讀資料
我們把資料存到硬碟裡面,接下的步驟要從硬碟把資料讀出來。我們首先定位到表。接著我們還可以查詢我們感興趣的資料。我們的查詢是通過 Table.iterrows() 這個迭代器,它把表中的每行提取出來。
table = f.root.detector.readout
energy = []
for x in table.iterrows():
energy.append(x)
- 1
- 2
- 3
- 4
3 建立陣列物件(Array object)
把資料放在table是資料組織很好的方式,但是當我們的資料並沒有那麼複雜,並沒有包含很多屬性,我們可以簡單地使用陣列來組織資料。比如我們想儲存矩陣資料,
features = np.random.rand(100,100000)
f = tables.openFile('feat.h5','w')
f.createArray(f.root,'feature',features)
f.close()
- 1
- 2
- 3
- 4
4 壓縮陣列(Compression Array)
HDF檔案還可以進行壓縮儲存,壓縮方式有blosc, zlib, 和 lzo。Zlib和lzo壓縮方式需要另外的包,blosc在tables是自帶的。我們需要定義一個filter來說明壓縮方式及壓縮深度。另外,我們使用creatCArray來建立壓縮矩陣。
f = tables.open_file('feat.h5', mode='w')
features = np.random.rand(100,100000)
filters=Filters(complevel=5,complib='blosc')
data_storage = f.createCArray(f.root,'feature',
Atom.from_dtype(features.dtype),
shape=features.shape,filters=filters)
data_storage[:]= features
f.close()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
5 壓縮可擴充套件陣列(Compression & Enlargeable Array)
壓縮陣列,初始化之後就不能改變大小,但現實很多時候,我們只知道維度,並不知道我們資料的長度。這個時候,我們需要這個陣列是可以擴充套件的。HDF檔案也提供這樣的介面,我們能夠擴充套件其一個維度。同CArray一樣,我們也先要定filter來宣告壓縮型別及深度。最重要的是,我們把可以擴充套件這個維度的shape設定為0。擴充套件資料的時候就使用append,這個資料shape必須為(1,data.shape[1])
f = tables.open_file('feat.h5', mode='w')
features = np.random.rand(100,100000)
filters=Filters(complevel=5,complib='blosc')
data_storage = f.createEArray(f.root,'feature',
Atom.from_dtype(features.dtype),
shape=(0,features.shape[1]),filters=filters)
for x in range(features.shape[0]):
data_storage.append(features[:,x])
f.close()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
上述我們儲存的資料是浮點型,當我們要儲存字串型別的,我們同樣定義:
image_name = '123fjo.jpg'
imageName_storage = f.createEArray(f.root,'filename',tables.StringAtom(itemsize=32),shape=(0,))
image_name = np.array([image_name],dtype=np.object)
imageName_storage.append(image_name)
- 1
- 2
- 3
- 4
- 5
如果我們不知道字串的位元組數,我們在初始化的時候就不需要填。接著,我們需要把python string型別轉換為numpy object型別。這樣在新增資料就沒有問題了。
當然,HDF遠遠不止這些內容,但是目前只用到這麼多。如果以後有需要,我們再來深入學習。
參考網站:
[1]: http://www.pytables.org/ 官方網站,很齊全但是內容太多了。
[2]: https://kastnerkyle.github.io/posts/using-pytables-for-larger-than-ram-data-processing/ 很好的例子,如果不想看太多,就看這個例子,基本就夠用了。
轉載:https://blog.csdn.net/lengyuexiang123/article/details/53558779
相關文章
- Python 讀取HDF5檔案Python
- (資料科學學習手札63)利用pandas讀寫HDF5檔案資料科學
- Python操作HDF5檔案示例詳解Python
- python---之iterPython
- python---之yamlPythonYAML
- 檔案操作之按照行讀寫檔案
- python---之nan,infPythonNaN
- Qt之qss檔案編寫QT
- numpy陣列之讀寫檔案陣列
- python之 檔案讀與寫Python
- (轉)Qt之qss檔案編寫QT
- python---之sorted函式Python函式
- python---之cls,和selfPython
- python學習之讀寫檔案Python
- Python之檔案讀寫小練Python
- python---之numpy.pad()Python
- python---之if _name_ == '_main_'PythonAI
- python---之物件導向selfPython物件
- Python之檔案讀取和寫入Python
- hadoop之 解析HDFS的寫檔案流程Hadoop
- 檔案排版(文字檔案讀寫)
- 檔案讀寫
- oracle 寫檔案Oracle
- Hadoop之HDFS檔案讀寫流程說明Hadoop
- Golang 讀、寫檔案Golang
- PHP寫入檔案PHP
- keras讀寫檔案Keras
- perl 讀寫檔案
- 檔案讀寫IO
- Oracle寫本地檔案Oracle
- java寫檔案(轉)Java
- 檔案的讀寫
- VBA建立文字檔案、讀寫文字檔案
- 【淺出 PHP】PHP 檔案操作 寫檔案PHP
- oracle sqr之不同判斷寫入不同的.LIS檔案Oracle
- 讀取檔案流並寫入檔案流
- TC中開啟檔案和寫入檔案
- Linux-檔案寫入和檔案同步Linux