【问题标题】:Python synchronised reading of sorted filesPython同步读取排序文件
【发布时间】:2011-01-03 08:46:01
【问题描述】:

我有两组文件,其中包含 CSV 格式的数据和一个公用键(时间戳) - 我需要按时间顺序浏览所有记录。

  • A 组:“环境数据”

    • 文件名的格式为 A_0001.csv、A_0002.csv 等。
    • 预排序升序
    • 键是时间戳,即YYYY-MM-DD HH:MM:SS
    • 包含 CSV/列格式的环境数据
    • 非常大,数 GB 的数据
  • B 组:“事件数据”

    • 文件名的格式为 B_0001.csv、B_0002.csv
    • 预排序升序
    • 键是时间戳,即YYYY-MM-DD HH:MM:SS
    • 包含 CSV/列格式的基于事件的数据
    • 与 A 组文件相比相对较小,

什么是最好的方法?

  • 预合并:使用各种方法之一将文件合并为单个排序输出,然后读取它以进行处理
  • 实时合并:实现代码以实时“合并”文件

我将对事物的后处理方面进行大量迭代。有什么想法或建议吗?我正在使用 Python。

【问题讨论】:

  • A、B文件编号是否对应?
  • 是否每个A文件都有一个B文件,反之亦然?文件 X_000i.csv 中的所有时间戳是否早于 (A, B) 和 i
  • A 组文件有数百个,B 组文件很少。每种文件中的数据/记录在记录随时间的分布方面是随机的。但是,A 组的记录数量非常多,因此通常会涵盖每个时间戳,但 B 组的记录数量要少得多,因此记录分布广泛。

标签: python file merge sorting


【解决方案1】:

这类似于关系连接。由于您的时间戳不必匹配,因此称为非等值连接。

Sort-Merge 是几种流行的算法之一。对于非等值连接,它运行良好。我认为这就是您所说的“合并前”。我不知道您所说的“实时合并”是什么意思,但我怀疑它仍然是一种简单的排序合并,这是一种很好的技术,被真实数据库大量使用。

嵌套循环也可以工作。在这种情况下,您在外循环中读取较小的表。在内部循环中,您可以从较大的表中找到所有“匹配”的行。这实际上是一种排序合并,但假设大表中会有多行与小表匹配。

顺便说一句,这将使您能够更恰当地为事件数据和环境数据之间的关系分配含义。嵌套循环可以很好地处理这一点,而不是读取大规模排序合并的结果并尝试确定您拥有哪种记录。

此外,您可以在读取较大的表格时对较小的表格进行“查找”。

当您进行非相等比较时,这很困难,因为您没有正确的键来从简单的字典中进行简单的检索。但是,您可以轻松扩展 dict(覆盖 __contains____getitem__)以对键进行范围比较,而不是简单的相等测试。

【讨论】:

    【解决方案2】:

    "YYYY-MM-DD HH:MM:SS" 可以通过简单的 ascii 比较进行排序。 重用外部合并逻辑怎么样?如果第一个字段是键,那么:

    for entry in os.popen("sort -m -t, -k1,1 file1 file2"):
        process(entry)
    

    【讨论】:

      【解决方案3】:

      您可以从文件中读取,例如 10000 条记录(或进一步分析告诉您最佳的任何数字)并即时合并。可能使用自定义类来封装IO;然后可以通过生成器协议(__iter__ + next)访问实际记录。

      这将是内存友好的,就完成操作的总时间而言可能非常好,并使您能够逐步生成输出。

      草图:

      class Foo(object):
      
          def __init__(self, env_filenames=[], event_filenames=[]):
              # open the files etc.
      
          def next(self):
              if self._cache = []:
                  # take care of reading more records
              else:
                  # return the first record and pop it from the cache
      
          # ... other stuff you need ...
      

      【讨论】:

        【解决方案4】:

        我认为将它导入数据库(mysql、sqlite 等)会比在脚本中合并它提供更好的性能。 db 通常具有用于加载 csv 的优化例程,并且连接可能与在 python 中合并 2 个 dicts(一个非常大)一样快或快得多。

        【讨论】:

        • 我曾想过这一点,但我们谈论的是数据仓库级别的记录。我总共有超过 100GB 的数据(数百万条记录)。也许我太快忽略它,但我认为考虑到文件/记录的设置,使用 db 进行合并/排序可以在 Python 中更快/更优雅地完成。
        【解决方案5】:

        我建议预先合并。

        读取文件会占用大量处理器时间。读取两个文件,两倍。由于您的程序将处理大量输入(大量文件,尤其是 A 组中的文件),我认为最好在一个文件中读取它,并将所有相关数据放在该文件中。它还会减少您需要的变量和read 语句的数量。

        这将改善算法的运行时间,我认为在这种情况下,这是决定使用这种方法的充分理由

        希望对你有帮助

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-03-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-06-08
          相关资源
          最近更新 更多