Python同步读取已排序文件
我有两组文件,它们包含CSV格式的数据,带有一个公共键(时间戳)——我需要按时间顺序遍历所有记录Python同步读取已排序文件,python,file,merge,sorting,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组文件相比相
- 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。我建议预合并 读取文件需要大量处理器时间。读取两个文件,两倍于此。由于您的程序将处理大量输入(大量文件,尤其是在组a中),我认为最好在一个文件中读取它,并将所有相关数据保存在该文件中。它还将减少所需的变量和
read
语句的数量
这将提高算法的运行时间,我认为这是在这个场景中决定使用这种方法的充分理由
希望这能有所帮助我认为将其导入数据库(mysql、sqlite等)会比在脚本中合并它提供更好的性能。db通常有用于加载csv的优化例程,并且连接速度可能与python中合并2个DICT(一个非常大)的速度一样快,甚至快得多。您可以从文件中读取,比如10000条记录(或者进一步分析告诉您的最佳数量),然后动态合并。可能使用自定义类来封装IO;然后可以通过生成器协议访问实际记录(
\uu iter\uuu
+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 ...
“YYYY-MM-DD HH:MM:SS”可以通过简单的ascii比较进行排序。
如何重用外部合并逻辑?如果第一个字段是键,则:
for entry in os.popen("sort -m -t, -k1,1 file1 file2"):
process(entry)
这类似于关系连接。因为您的时间戳不必匹配,所以它被称为非等联接 排序合并是几种流行的算法之一。对于非等联接,它工作得很好。我想这就是所谓的“预合并”。我不知道你所说的“实时合并”是什么意思,但我怀疑它仍然是一种简单的排序合并,这是一种很好的技术,被实际数据库大量使用 嵌套循环也可以工作。在本例中,您读取外部循环中较小的表。在内部循环中,您可以从较大的表中找到所有“匹配”行。这实际上是一种排序合并,但假设大表中有多行与小表匹配 顺便说一句,这将允许您更正确地为事件数据和环境数据之间的关系分配意义。嵌套循环处理得很好,而不是读取大规模排序合并的结果并试图确定您得到的是哪种类型的记录 此外,您还可以在读取较大表的同时对较小的表进行“查找”
当您进行非相等比较时,这很难做到,因为您没有适当的键来从简单的dict执行简单的检索。但是,您可以轻松地扩展dict(覆盖
\uuuuuu contains\uuuuuuuuuu
和\uuuuu getitem\uuuuuuuuuu
)在一个键上进行范围比较,而不是简单的相等性测试。a和B文件号是否相互对应?是否每个a文件都有一个B文件,反之亦然?对于X in(A,B)和i