2016-10-16 26 views
0

我目前有一百萬行數據集,每個數據集大約有10000列(可變長度)。在Python中向HDF5文件寫入大量數字

現在我想將這些數據寫入HDF5文件,以便稍後使用它。 我得到這個工作,但它是令人難以置信的慢。即使1000個值也需要花費幾分鐘時間才能存儲在HDF5文件中。

我一直在尋找無處不在,包括SO和H5Py文檔,但我真的找不到任何描述我的用例的東西,但我知道它可以完成。

下面我做了一個演示的源代碼來闡述什麼我現在在做:

import h5py 
import numpy as np 

# I am using just random values here 
# I know I can use h5py broadcasts and I have seen it being used before. 
# But the issue I have is that I need to save around a million rows with each 10000 values 
# so I can't keep the entire array in memory. 
random_ints = np.random.random(size = (5000,10000)) 

# See http://stackoverflow.com/a/36902906/3991199 for "libver='latest'" 
with h5py.File('my.data.hdf5', "w", libver='latest') as f: 
    X = f.create_dataset("X", (5000,10000)) 
    for i1 in range(0, 5000): 
     for i2 in range(0, 10000): 
      X[i1,i2] = random_ints[i1,i2] 

     if i1 != 0 and i1 % 1000 == 0: 
      print "Done %d values..." % i1 

該數據來自一個數據庫,它不是一個預先生成NP陣列,如被看到的源代碼。

如果您運行此代碼,您可以看到打印出「完成1000個值」需要很長時間。

我在使用8GB RAM,Ubuntu 16.04 LTS和Intel Core M(與Core i5執行類似操作)和SSD的筆記本電腦上使用,這必須足以執行比此更快的操作。

我讀過有關廣播的位置:http://docs.h5py.org/en/latest/high/dataset.html

當我使用這樣的:

for i1 in range(0, 5000): 
     X[i1,:] = random_ints[i1] 

它已經進入一個幅度較快(做的是幾秒鐘)。但我不知道如何使用可變長度數據集(列是可變長度的)。如果能夠了解如何完成這項工作,那將是非常好的,因爲我認爲我現在對HDF5的概念不太瞭解。:)非常感謝!

+0

是的,迭代並將單個數字寫入文件(甚至寫入內存numpy數組)很慢。爲了提高速度,您希望使用更大的塊,數千個數字。 – hpaulj

+0

@hpaulj感謝您的單挑。你能詳細說明一下嗎?我該如何處理可變長度?我的直覺告訴我只需將列填充到最大的對應列,然後使用我的問題中的第二個代碼塊插入數字。這是解決這個問題的好方法嗎? –

+0

我沒有看到使用可變長度的演示代碼中的任何內容。你所要做的就是按數組或行的方式將數組寫入文件。 – hpaulj

回答

1

http://docs.h5py.org/en/latest/special.html

,並使用開放H5文件f,我想:

dt = h5py.special_dtype(vlen=np.dtype('int32')) 
vset=f.create_dataset('vset', (100,), dtype=dt) 

設置元素逐一:

vset[0]=np.random.randint(0,100,1000) # set just one element 
for i in range(100): # set all arrays of varying length 
    vset[i]=np.random.randint(0,100,i) 
vset[:]  # view the dataset 

或者使對象數組:

D=np.empty((100,),dtype=object) 
for i in range(100): # setting that in same way 
    D[i]=np.random.randint(0,100,i) 

vset[:]=D # write it to the file 

vset[:]=D[::-1] # or write it in reverse order 

最後一次寫入的一部分:

In [587]: vset[-10:] 
Out[587]: 
array([array([52, 52, 46, 80, 5, 89, 6, 63, 21]), 
     array([38, 95, 51, 35, 66, 44, 29, 26]), 
     array([51, 96, 3, 64, 55, 31, 18]), 
     array([85, 96, 30, 82, 33, 45]), array([28, 37, 61, 57, 88]), 
     array([76, 65, 5, 29]), array([78, 29, 72]), array([77, 32]), 
     array([5]), array([], dtype=int32)], dtype=object) 

我可以查看與元件的部分:

In [593]: vset[3][:10] 
Out[593]: array([86, 26, 2, 79, 90, 67, 66, 5, 63, 68]) 

但我不能把它當作一個二維數組:vset[3,:10]。它是一個數組數組。

+0

它的工作原理,感謝讓我明白這一切! –