验证记录在Python / PyTables中是唯一的有效方法

时间:2009-08-22 04:25:40

标签: python

我在PyTables中有一张表,有大约5000万条记录。两个字段(特别是userID和date)的组合应该是唯一的(即用户每天最多只能有一条记录),但我需要验证确实如此。

说明一下,我的表格如下:

userID |   date
A      |    1
A      |    2
B      |    1
B      |    2
B      |    2   <- bad! Problem with the data!

其他详情:

  • 该表目前“大部分”已排序。
  • 我几乎不能拉一列 作为一个numpy数组存入内存,但我 不能把两个拉成内存的 同时。
  • userID和date都是整数

3 个答案:

答案 0 :(得分:4)

似乎PyTables中的索引仅限于单列。

我建议添加一个哈希列并在其上添加索引。您的唯一数据被定义为数据库中其他列的串联。分隔符将确保没有两个不同的行产生相同的唯一数据。哈希列可能只是这个唯一的字符串,但如果您的数据很长,您将需要使用哈希函数。像md5或sha1这样的快速哈希函数非常适合这个应用程序。

计算散列数据并检查它是否在数据库中。如果是这样,您知道您遇到了一些重复的数据。如果没有,您可以安全地添加它。

答案 1 :(得分:1)

多年以后我仍然有同样的问题,但是由于索引和查询的能力,这个问题只是有点痛苦,这取决于你的表的大小。使用readWhere或getListWhere我认为问题是大约O(n)

这是我做的...... 1.我创建了一个有两个指标的表格。你可以在PyTables中使用多个指标:

http://pytables.github.com/usersguide/optimization.html#indexed-searches

一旦您的表格为indexed,我也会使用LZO压缩,您可以执行以下操作:

import tables
h5f = tables.openFile('filename.h5')
tbl = h5f.getNode('/data','data_table') # assumes group data and table data_table
counter += 0

for row in tbl:
    ts = row['date'] # timestamp (ts) or date
    uid = row['userID']
    query = '(date == %d) & (userID == "%s")' % (ts, uid)
    result = tbl.readWhere(query)
    if len(result) > 1:
        # Do something here
        pass
    counter += 1
    if counter % 1000 == 0: print '%d rows processed'

现在我在这里写的代码实际上有点慢。我确信那里有一些PyTables大师可以给你一个更好的答案。但这是我对表现的看法:

如果你知道你开始使用干净的数据,即(没有重复数据),那么你所要做的就是查询表一次找到你感兴趣的键,这意味着你只需要这样做:

ts = row['date'] # timestamp (ts) or date
uid = row['userID']
query = '(date == %d) & (userID == "%s")' % (ts, uid)
result = tbl.getListWhere(query)
if len(result) == 0:
    # key pair is not in table
    # do what you were going to do
    pass
elif len(result) > 1:
    # Do something here, like get a handle to the row and update instead of append.
    pass

如果您有足够的时间检查重复项,请创建一个后台进程,使用您的文件抓取目录并搜索重复项。

我希望这有助于其他人。

答案 2 :(得分:0)

我对PyTables了解不多,但我会尝试这种方法

  1. 对于每个userID,获取所有(userID, date)
  2. assert len(rows)==len(set(rows)) - 如果(userID, date)列表中包含的所有rows元组都是唯一的,则此断言成立