2014-09-30 6 views
0

У меня есть два текстовых файла, каждый из примерно 1 ГБ, где каждая строка содержит 60 столбцов. Есть 6 столбцов, которые являются ключами для сравнения в каждом файле.Python для сравнения огромных текстовых файлов на основе нескольких ключей

Пример:

файл1: 4|null|null|null|null|null|3590740374739|20077|7739662|75414741|

файл2: 4|null|11|333|asdsd|null|3590740374739|20077|7739662|75414741|

Вот две строки равны как столбцы 7,8,9 и 10 являются одинаковыми в двух файлах (клавишах). Я попробовал образец для сравнения файлов без учета ключей, который отлично работает, но мне нужно сравнивать на основе ключей, а не символов для символов в каждой строке.

Вот пример кода, который я пытался сравнить, не рассматривая ключи.

matched = open('matchedrecords.txt','w') 

with open('srcone.txt') as b: 
    blines = set(b) 

with open('srctwo.txt') as a: 
    alines = set(a) 

with open('notInfirstSource.txt', 'w') as result: 
    for line in alines: 
    if line not in blines: 
     result.write(line) 
    else: 
     matched.write(line)  

with open('notInsecondSource.txt', 'w') as non: 
    for lin in blines: 
     if lin not in alines: 
     non.write(lin) 

matched.close() 
+0

Могут ли те же ключи отображаться дважды (в других строках) внутри файла? Если да, то что должно произойти в этом случае? –

+0

Основной метод использования здесь - сортировать оба файла и проходить через них одновременно. Кроме того, операция тяжелой сортировки - это просто линейная (прогулка через нее) функция. – Wolph

+0

Спасибо за комментарий :). Комбинации ключей уникальны в обоих файлах @ TimPietzcker. Потому что одним из ключей является метка даты. –

ответ

0

Это один из способов вы можете сравнить линии на основе ключей/столбцов, но я не уверен, насколько эффективно это.

matched =open('matchedrecords.txt','w') 
    with open('srcone.txt') as b: 
     blines = set(b) 
    with open('srctwo.txt') as a: 
     alines= set(a) 

     # List of columns or keys to compare 
     list_of_columns_to_compare=[7,8,9] 

     a_columns=[] 
     b_columns=[] 

     for blin in blines : 
      for alin in alines: 
       for column_no in list_of_columns_to_compare : 
        # Appending columns to a list to compare 
        b_columns.append(blin.split('|')[column_no]) 
        a_columns.append(alin.split('|')[column_no]) 

        if a_columns == b_columns: 
         matched.write(blin + " = " + alin) 
+0

Здравствуйте, @RBH Спасибо за ваш ответ :) .. Я пробовал с данными 300 Мб и занимаю столько времени, сколько огромного количества итераций. –

0

Взяв пример с recipe for KeyedSets на ActiveState, вы можете создать набор, а затем просто использовать набор пересечение и разность множеств для получения результатов:

import collections 

class Set(collections.Set): 
    @staticmethod 
    def key(s): return tuple(s.split('|')[6:10]) 
    def __init__(self, it): self._dict = {self.key(s):s for s in it} 
    def __len__(self): return len(self._dict) 
    def __iter__(self): return self._dict.itervalues() 
    def __contains__(self, value): return self.key(value) in self._dict 

data = {} 
for filename in 'srcone.txt', 'srctwo.txt': 
    with open(filename) as f: 
     data[filename] = Set(f) 

with open('notInFirstSource.txt', 'w') as f: 
    for lines in data['srctwo.txt'] - data['srcone.txt']: 
     f.write(''.join(lines)) 

with open('notInSecondSource.txt', 'w') as f: 
    for lines in data['srcone.txt'] - data['srctwo.txt']: 
     f.write(''.join(lines)) 

with open('matchedrecords.txt', 'w') as f: 
    for lines in data['srcone.txt'] & data['srctwo.txt']: 
     f.write(''.join(lines)) 
+0

Hey ROb ... не могли бы вы объяснить мне функцию _init_, написанную выше. И на самом деле уникальные ключи, которые нужно сравнить, не могут быть серийными, я имею в виду, что это похоже на (6,7,9,11,14) –

0

Наконец, я мог бы добиться этого в очень меньше времени на использование словарей. i.e 370 МБ данных по сравнению с файлом данных 270 МБ за 50 секунд Максимум (с использованием кортежа в качестве ключа). Это сценарий:

reader = open("fileA",'r') 
    reader2 = open("fileB",'r') 
    TmpDict ={} 
    TmpDict2={} 
    for line in reader: 
     line = line.strip() 
     TmpArr=line.split('|') 
     #Forming a dictionary with below columns as keys 
     TmpDict[TmpArr[2],TmpArr[3],TmpArr[11],TmpArr[12],TmpArr[13],TmpArr[14]]=line 
    for line in reader2: 
     line = line.strip() 
     TmpArr=line.split('|') 
     TmpDict2[TmpArr[2],TmpArr[3],TmpArr[11],TmpArr[12],TmpArr[13],TmpArr[14]]=line 
    outfile = open('MatchedRecords.txt', 'w') 
    outfileNonMatchedB=open('notInB','w') 
    outfileNonMatchedA=open('notInA','w') 
    for k,v in TmpDict.iteritems(): 
     if k in TmpDict2: 
      outfile.write(v+ '\n') 
     else: 
      outfileNonMatchedB.write(v+'\n') 
    outfile.close() 
    outfileNonMatchedB.close() 
    for k,v in TmpDict2.iteritems(): 
     if k not in TmpDict: 
      outfileNonMatchedA.write(v+'\n') 
    outfileNonMatchedA.close() 

Любые улучшения можно было бы сделать для этого? Предложи мне ! Thanks

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