2016-06-11 77 views
1

我想寫入一個vlen hdf5數據集,因爲我使用h5py.Dataset.write_direct來加速這個過程。假設我有numpy的陣列的列表(例如,通過cv2.findContours給出),並通過數據集:忽略numpy的數組創建中的嵌套結構

dataset = h5file.create_dataset('dataset', \ 
           shape=..., \ 
           dtype=h5py.special_type(vlen='int32')) 
contours = [numpy array, ...] 

對於寫contours由片dest給定一個目標,我必須首先轉換contours到numpy的陣列的numpy的陣列:

contours = numpy.array(contours) # shape=(len(contours),); dtype=object 
dataset.write_direct(contours, None, dest) 

但是這僅適用,如果在輪廓所有numpy的陣列具有不同的形狀,例如:

contours = [np.zeros((10,), 'int32'), np.zeros((10,), 'int32')] 
contours = numpy.array(contours) # shape=(2,10); dtype='int32' 

問題是:我如何告訴numpy創建一個對象數組?


可能的解決方案:

手動創建:

contours_np = np.empty((len(contours),), dtype=object) 
for i, contour in enumerate(contours): 
    contours_np[i] = contour 

但循環是超級慢,因此利用map

map(lambda (i, contour): contour.__setitem_(i, contour), \ 
    enumerate(contours)) 

我測試了第二個選項,這是兩倍於上述速度,但也超級醜陋:

contours = np.array(contours + [None])[:-1] 

這裏是微基準測試:

l = [np.random.normal(size=100) for _ in range(1000)] 

選項1:

$ start = time.time(); l_array = np.zeros(shape=(len(l),), dtype='O'); map(lambda (i, c): l_array.__setitem__(i, c), enumerate(l)); end = time.time(); print("%fms" % ((end - start) * 10**3)) 
0.950098ms 

選項2:

$ start = time.time(); np.array(l + [None])[:-1]; end = time.time(); print("%fms" % ((end - start) * 10**3)) 
0.409842ms 

這看起來的醜樣,任何其他建議?

回答

1

在這個版本中

contours_np = np.empty((len(contours),), dtype=object) 
for i, contour in enumerate(contours): 
    contours_np[i] = contour 

您可以用單個語句

contours_np[...] = contours 
更換循環
+0

這就是我一直在尋找的:) – user1447257

0

一種解決方案似乎是先創建「外部」數組(帶有'object'dtype),然後用內部數組填充元素。

這樣:

contours = [np.zeros((10,), 'int32'), np.zeros((10,), 'int32')] 
a = np.empty(len(contours), dtype=np.object) 
for i in range(len(contours)): 
    a[i] = contours[i] 
print(a) 
print() 
print(repr(a)) 

結果

[array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int32) 
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int32)] 

array([array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int32), 
     array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int32)], dtype=object)