我想写入 vlen hdf5 数据集,为此我使用 h5py.Dataset.write_direct
来加速该过程。假设我有一个 numpy 数组列表(例如由 cv2.findContours
给出)和数据集:
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))
我测试了第二个选项,它的速度是上面的两倍,但也 super 难看:
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
这看起来有点难看,还有其他建议吗?
最佳答案
在此版本中
contours_np = np.empty((len(contours),), dtype=object)
for i, contour in enumerate(contours):
contours_np[i] = contour
您可以用单个语句替换循环
contours_np[...] = contours
关于python - 忽略 numpy 数组创建中的嵌套结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37762275/