我使用HDF5
来存储uint8s
(400x1210000000)的非常大的数据集。列中存在大量冗余(97%的列不是唯一的)。我需要有效地合并重复的列。这意味着我需要删除重复的列,同时存储元数据以记住合并了哪些列。在
我目前使用Python和^ {CD3>},但是如果有人有一个高效的C++解决方案,我可以简单地使用^
我当前的解决方案是将数据集的块加载到NumPy
数组中,并使用dictionary
来存储唯一的列和元数据。在
注意:可以找到HashableNDArray
类here。我刚把它改名了。在
def find_column_redundancy(dataset):
n_columns = dataset.shape[1]
block_size = 500000
n_blocks = int(ceil(float(n_columns) / float(block_size)))
d = {}
analysed_column_count = 0
for block in xrange(n_blocks):
block_offset = block*block_size
block_data = dataset[:, block_offset : block_offset+block_size]
for i in xrange(block_data.shape[1]):
hashable_array = HashableNDArray(np.ascontiguousarray(block_data[:, i]))
d[hashable_array] = np.append(d.get(hashable_array, np.array([], dtype=np.int32)), block_offset + i)
analysed_column_count += 1
return d
遍历所有列之后,我返回一个dictionary
,我用它来编写一个新的HDF5
数据集,去掉冗余。在
我需要帮助,这不可能是最好的!在
谢谢!在
我用kernprof做了一些分析,并优化了我的代码。在
最大的瓶颈是HashableNDArray对象的实例化。我发现,通过使numpy数组为只读,我可以散列它们的数据缓冲区,而不必使用包装器类。对于数据的提取,哈希处理的速度似乎要快得多。为了恢复列数据,我使用
np.frombuffer(dict_key, dtype=np.uint8)
。我还通过将dictionary替换为defaultdict并消除try/except块,获得了一个小的加速。
由于我的数据只包含二进制值,我发现在列上使用np.packbits可以在存储键时节省8倍的内存,并且仍然允许匹配相同的列。使用np.unpackbits时,唯一需要记住的是列的实际长度,因为numpy填充了不完整的字节,后面有0。
最后,我微调了块大小以使用最大可用内存量。这允许稍长的磁盘读取时间和更好的CPU使用率。在
这个函数以前在我的数据上运行大约18小时,现在只需要~0.5小时!在
相关问题 更多 >
编程相关推荐