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)