比较多个csv文件并查找匹配项

时间:2013-07-08 14:44:21

标签: python optimization csv large-files multiple-databases

我有两个带csv文件的文件夹。一组“主”文件和一组“无与伦比”的文件。在主文件(~25个文件,总共约50,000行)中,有唯一的ID。不匹配文件的每一行(~250个文件,总共大约700,000行)应该在行中具有与其中一个主文件中的单个id匹配的id。在每个不匹配的文件中,所有id都应与单个主文件匹配。此外,无法匹配的所有ID都应属于单个主数据。

不幸的是,列并不总是一致的,id字段可能出现在row [2]或row [155]中。 (我正在使用python)我最初使用set.intersection并找到长度为>的匹配实例。 5(缺少值标有'。'或只是我想避免的空白。)但很快就知道运行时间太长了。一般来说,我需要将“不匹配”的文件与其“主”文件进行匹配,并且我希望使用带有id的“不匹配”文件中的列索引。因此,如果不匹配的文件unmatched_a具有主要属于master_d的ID,并且unmatched_a中的匹配列是第35列,则它将返回一行:

unmatched_a,master_d,35

道歉,如果不清楚的话 - 我很乐意尝试澄清是否需要。 stackoverflow上的第一篇文章。我可以发布我到目前为止的代码,但我不认为它会有用,因为问题在于我的方法是比较多个(相对)大的csv文件。我看到很多帖子比较了两个已知index_id的csv文件或文件,但没有多个文件和多个可能匹配的文件。

1 个答案:

答案 0 :(得分:0)

您必须首先将所有主文件读入内存 - 这是不可避免的,因为匹配的ID可能位于主文件中的任何位置。

然后,对于每个不匹配的文件,您可以读取第一条记录并找到它的id(给出id列),然后找到包含该id的主文件(为您提供匹配的主文件)。根据你的描述,一旦你匹配了第一条记录,所有其余的id都将在同一个文件中,所以你已经完成了。

将ID读入集合 - 检查成员资格为O(1)。将每个集合放入一个键入master_file名称的dict中。迭代主人的词是O(n)。因此,对于主文件的数量和不匹配文件的数量,这是O(nm)。

import csv

def read_master_file(master_file):
    with open(master_file, "r") as file:
        reader = csv.reader(file)
        ids = set(line[0] for line in file) # I assumed the id is the first value in each row in the master files. Depending on the file format you will want to change this.
    return ids

def load_master_files(file_list):
    return {file: read_master_file(file) for file in file_list}

def check_unmatched_file(unmatched_file, master_dict):
    with open(unmatched_file, "r") as file:
        reader = csv.reader(file)
        record = next(reader)
    for id_column in [2, 155]: # if you can identify an id by semantics, rather than by attempting to match it against the masters, you can reduce running time by 25% by finding the id before this step
        id = record[id_column]
        for master in master_dict:
            if id in master_dict[master]:
                return unmatched_file, master, id
    return None # id not in any master. Feel free to return or raise whatever works best for you