1. 程式人生 > >python資料探勘常用的幾種大資料儲存格式

python資料探勘常用的幾種大資料儲存格式

一直想找個機會好好學習下這塊的知識,但是畢竟實踐出真知,下面的就按照我自己使用過的一點點補充吧^^

pickle 儲存物件

專案中常用pickle,不瞭解前以為是多麼高大上的東西,瞭解之後發現並不神祕,用一句話概括就是持久化操作。之前做java那麼久,還是第一次接觸python的持久化操作,明顯還是跟java的持久化機制差了一大截。
雖然簡單,但是pickle真的很好用,因為他可以儲存訓練了一半的模型,下次接著訓練!厲害吧!

 import Cpickle as pickle #python2
 import pickle #python3

怎麼用 dump and load:

基本介面:
pickle.dump(obj, file, [,protocol])
註解:將物件obj儲存到檔案file中去。
protocol為序列化使用的協議版本,0:ASCII協議,所序列化的物件使用可列印的ASCII碼錶示;1:老式的二進位制協議;2:2.3版本引入的新二進位制協議,較以前的更高效。其中協議0和1相容老版本的python。protocol預設值為0。
file:物件儲存到的類檔案物件。file必須有write()介面, file可以是一個以’w’方式開啟的檔案或者一個StringIO物件或者其他任何實現write()介面的物件。如果protocol>=1,檔案物件需要是二進位制模式開啟的。

pickle.load(file)
註解:從file中讀取一個字串,並將它重構為原來的python物件。
file:類檔案物件,有read()和readline()介面。

>>> a1 = 'apple'  
>>> b1 = {1: 'One', 2: 'Two', 3: 'Three'}  
>>> c1 = ['fee', 'fie', 'foe', 'fum']  
>>> f1 = file('temp.pkl', 'wb')  
>>> pickle.dump(a1, f1, True
) >>> pickle.dump(b1, f1, True) >>> pickle.dump(c1, f1, True) >>> f1.close() >>> f2 = file('temp.pkl', 'rb') >>> a2 = pickle.load(f2) >>> a2 'apple' >>> b2 = pickle.load(f2) >>> b2 {1: 'One', 2: 'Two', 3: 'Three'} >>> c2 = pickle.load(f2) >>> c2 ['fee', 'fie', 'foe', 'fum'] >>> f2.close()

我用的時候:

pickle.dump(encoder, open('../../models/encoder.pkl', 'wb'))

除此之外我還遇到了一個錯誤,pickle在load一個訓練了一半的模型的時候報EOFError,查了一下發現原來是因為我寫入的時候是’wb’寫入,但讀的時候是用的’r’,應該用’rb’,代表著二進位制格式讀寫。最好這樣寫下:

with open(model.model_history_fname,'rb') as f:
    # net.train_history_ = pickle.load(f)
    try:
        net.train_history_=pickle.load(f)
    except EOFError:
        net.train_history_ = None

pickle操作還有一些複雜一點的物件操作,感覺在資料探勘中不太常用,我是沒用過啦,就不細看了~

numpy.memmap記憶體對映方式

將大檔案分成小段讀寫,而不是一次性讀入整個檔案,節約記憶體空間。後悔比賽的時候一次都沒試過,後面總是溢位溢位,那時候只求用最快的方式投機取巧的解決,哎,喪失了最好的學習機會。

使用函式np.memmap並傳入一個檔案路徑、資料型別、形狀以及檔案模式,即可建立一個新的memmap:
memmap(filename,dtype=uint8,mode=“r+”,offset=0,shape,order=‘C’)
其中,offset是檔案中儲存資料的起始位置;mode可以是c(不寫入的修改)r+(可讀寫)w+(建立或是覆蓋已有檔案)。
我用的時候:

X_fp = np.memmap(X_fname, dtype=np.float32, mode='w+', shape=X_shape)

發現這個可以和csv讀寫結合在一起,起到邊讀邊寫的效果,操作就是用iterrows按行讀取檔案,然後每一行都flush儲存。看了下記憶體幾乎沒有消耗,超級贊。
建立後是純0的,對memmap切片將會返回磁碟上的資料的檢視:

section = mmap[:5]

如果將資料賦值給這些檢視:資料會先被快取在記憶體中(就像是Python的檔案物件),呼叫flush即可將其寫入磁碟。

section[:] = np.random.randn(5, 10000)
mmap.flush()
del mmap

在使用的時候它和ndarray幾乎沒有區別。
有幾個notes:

The memmap object can be used anywhere an ndarray is accepted. Given a memmap fp, isinstance(fp, numpy.ndarray) returns True.
Memory-mapped files cannot be larger than 2GB on 32-bit systems.

讀的時候只要把mode改成mode=’r’就可以了,我用的時候:

X = np.memmap(X_fname, dtype=np.float32, mode=’r’, shape=X_shape)