2013-07-08 2 views
0

У меня есть две папки с файлами csv. Группа «основных» файлов и группа «непревзойденных» файлов. В основных файлах (~ 25 файлов, всего около 50 000 строк) есть уникальные идентификаторы. Каждая строка непревзойденных файлов (~ 250 файлов, всего около 700 000 строк) должна иметь идентификатор в строке, которая соответствует одному идентификатору в одном из основных файлов. В каждом из непревзойденных файлов все идентификаторы должны совпадать с одним основным файлом. Кроме того, все идентификаторы в непревзойденном должны находиться в пределах одного мастера.Сравнение нескольких файлов csv и поиск совпадений

К сожалению, столбцы не всегда согласованы, а поле id может отображаться в строке [2] или в строке [155]. (Я использую для этого python). Первоначально я использовал set.intersection и находил совпадающие экземпляры, где длина> 5 (отсутствуют значения, отмеченные знаком «.» Или просто пробел, который я хотел избежать.), Но быстро научился время выполнения слишком велико. Вообще говоря, мне нужно сопоставить «непревзойденные» файлы с его «основным» файлом, и я хотел бы иметь индекс столбца из «непревзойденного» файла с используемым идентификатором. Так что если непревзойденный файл unmatched_a имеет идентификаторы, которые в основном попадают под master_d, а столбец соответствия в unmatched_a на колонке 35, она возвращает строку:

unmatched_a, master_d, 35

Извинения, если это неясно - Я был бы рад попробовать и уточнить, если потребуется. Первая запись в stackoverflow. Я могу опубликовать код, который у меня есть до сих пор, но я не думаю, что это было бы полезно, потому что проблема связана с моим методом сравнения нескольких (относительно больших) CSV-файлов. Я видел много сообщений, сравнивающих два файла csv или файлы, где известен index_id, но ничего с несколькими файлами и несколькими файлами с потенциальными совпадениями.

+0

Что именно вы делаете с каждым непревзойденным файлом? Можете ли вы дождаться, чтобы узнать, какой мастер-файл для него до конца обработки этого файла? – cmd

+0

В каждом файле содержится только один столбец с идентификаторами? –

+0

@ cmd - до конца все будет хорошо. способ, которым я занимался, был строковым, но это приводит к 50 000 * 700 000 итераций. Я посмотрел на каждую строку, создал набор, вынул значения с <5 символами и посмотрел на каждую строку в главном, чтобы найти совпадение. @SimonRighley - основные файлы не отличаются друг от друга и не обязательно один идентификатор - их не более четырех, и каждый раз он не совпадает друг с другом. – jack

ответ

0

Вам нужно будет начать с чтения всех основных файлов в память - это неизбежно, так как соответствующие идентификаторы могут быть в любом месте основных файлов.

Затем для каждого непревзойденного файла вы можете прочитать первую запись и найти ее идентификатор (дающий столбец идентификатора), а затем найти основной файл, содержащий этот идентификатор (дающий согласованный мастер-файл). Согласно вашему описанию, как только вы сопоставляете первую запись, все остальные идентификаторы будут в одном файле, так что вы закончили.

Чтение идентификаторов в набор - проверка членства - O (1). Поместите каждый набор в файл с ключом для имени файла master_file. Итерацией по типу мастеров является 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 

 Смежные вопросы

  • Нет связанных вопросов^_^