【问题标题】:Efficient way to verify that records are unique in Python/PyTables验证记录在 Python/PyTables 中是否唯一的有效方法
【发布时间】:2012-07-03 08:07:29
【问题描述】:

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

例如,我的表格如下所示:

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

其他细节:

  • 该表目前“大部分”已排序。
  • 我只能勉强拉一根柱子 作为一个numpy数组进入内存,但我 无法将两个拉入内存 同一时间。
  • 用户 ID 和日期都是整数

【问题讨论】:

    标签: python


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

      多年后我仍然有同样的问题,但是借助索引和查询的力量,这个问题只是稍微痛苦,具体取决于表的大小。使用 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
      

      如果您有大量时间检查重复项,请创建一个后台进程,该进程会在您的文件所在目录上爬网并搜索重复项。

      我希望这对其他人有所帮助。

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-26
          • 1970-01-01
          • 1970-01-01
          • 2019-06-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多