python - 在具有 500e6 行的 hdf5 pytable 中查找重复项

标签 python hdf5 pytables

问题

我有一个大型(> 500e6 行)数据集,我已将其放入 pytables 数据库中。

假设第一列是 ID,第二列是每个 ID 的计数器。每个 ID 计数器组合都必须是唯一的。我要查找的 500e6 行中有一个非唯一行。

作为初学者,我做过这样的事情:

index1 = db.cols.id.create_index()
index2 = db.cols.counts.create_index()
for row in db:
    query = '(id == %d) & (counts == %d)' % (row['id'],  row['counts'])
    result = th.readWhere(query)
    if len(result) > 1:
        print row

我承认这是一种蛮力方法。有什么改进建议吗?

更新

当前的暴力破解运行时间为 8421 分钟。

解决方案 感谢大家的意见和建议。我设法使用以下方法将运行时间降低到 2364.7 秒:

ex = tb.Expr('(x * 65536) + y', uservars = {"x":th.cols.id, "y":th.cols.counts})
ex = tb.Expr(expr)
ex.setOutput(th.cols.hash)
ex.eval()
indexrows = th.cols.hash.create_csindex(filters=filters)

ref = None
dups = []
for row in th.itersorted(sortby=th.cols.hash):
  if row['hash'] == ref:
    dups.append(row['hash'] )
  ref = row['hash']

print("ids: ", np.right_shift(np.array(dups, dtype=np.int64), 16))
print("counts: ", np.array(dups, dtype=np.int64) & 65536-1)

我可以生成一个完美的散列,因为我的最大值小于 2^16。我有效地将两列打包成一个 32 位整数。

生成 csindex 后,遍历排序后的值并对重复值进行邻居测试就相当简单了。

这个方法可能需要稍微调整一下,但我正在测试一些可能提供更自然解决方案的替代方案。

最佳答案

我想到了两种明显的技术:散列和排序。

A) 定义一个散列函数,将 ID 和 Counter 组合成一个紧凑的值。

B) 计算每个哈希码出现的频率

C) 从您的数据中选择所有具有哈希冲突的数据(这应该是一个“小得多”的数据集)

D) 对该数据集进行排序以查找重复项。

需要选择 A) 中的哈希函数,使其适合主存,同时提供足够的选择性。也许为此使用两个大小为 2^30 左右的位集。您可以承受 5-10% 的冲突,这仍应将数据集大小减小到足以允许之后在内存中进行快速排序。

这本质上是一个布隆过滤器。

关于python - 在具有 500e6 行的 hdf5 pytable 中查找重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20743135/

相关文章:

python - 如何获取 SSL 证书以查看它是否已过期

hdf5 - h5py 是否能够自动将 python 字典转换为 hdf5 组?

python - Pandas HDFStore 从内存中卸载数据帧

python - 如何使用 Dask 在此 "nested"结构化数组上运行计算?

python - 使用带有 DateTimeIndex 项的 select 从 HDFStore 检索 Pandas DataFrame 时缺少一个值

python - groupby 并返回前 n 组的所有行

python - 获取 key 中的第二项

python - 旧版本 python 的 OrderedDict

hdf5 - 我可以创建指向 hyperslab 的 HDF5 链接吗?

c++ - 从 HDF5 vector 填充 Armadillo vec