Python同步读取已排序的文件

时间:2010-01-09 22:52:52

标签: python file merge sorting

我有两组文件,其中包含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组文件相比相对较小,< 100 MB

什么是最好的方法?

  • 预合并:使用其中一种配方将文件合并为一个已排序的输出,然后将其读取以进行处理
  • 实时合并:实施代码以实时“合并”文件

我将运行许多后处理方面的迭代。有什么想法或建议吗?我正在使用Python。

5 个答案:

答案 0 :(得分:2)

我想将它导入db(mysql,sqlite等)会比在脚本中合并它更好。 db通常具有用于加载csv的优化例程,并且连接可能比在python中合并2个dicts(一个非常大)更快或更快。

答案 1 :(得分:2)

“YYYY-MM-DD HH:MM:SS”可以通过简单的ascii比较进行分类。 如何重用外部合并逻辑?如果第一个字段是关键,那么:

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

答案 2 :(得分:1)

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

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

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

这,BTW,将允许您更恰当地为事件数据和环境数据之间的关系分配含义。嵌套循环不是读取大规模排序合并的结果,而是试图确定您已经获得了哪种记录,而是处理得很好。

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

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

答案 3 :(得分:0)

我建议合并前。

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

这将改善算法的运行时间,我认为这个场景中有足够的理由决定使用这种方法

希望这有帮助

答案 4 :(得分:0)

您可以从文件中读取,例如,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 ...