2017-02-15 7 views
0

Мне просто интересно, есть ли лучший способ сделать этот алгоритм. Я считаю, что мне нужно делать этот тип операции довольно часто, и то, как я сейчас занимаюсь, занимает много часов, так как я считаю, что это будет считаться алгоритмом n^2. Я приложу его ниже.Более эффективный способ выполнения этого алгоритма поиска?

import csv 

with open("location1", 'r') as main: 
    csvMain = csv.reader(main) 
    mainList = list(csvMain) 

with open("location2", 'r') as anno: 
    csvAnno = csv.reader(anno) 
    annoList = list(csvAnno) 

tempList = [] 
output = [] 

for full in mainList: 
    geneName = full[2].lower() 
    for annot in annoList: 
     if geneName == annot[2].lower(): 
      tempList.extend(full) 
      tempList.append(annot[3]) 
      tempList.append(annot[4]) 
      tempList.append(annot[5]) 
      tempList.append(annot[6]) 
      output.append(tempList) 

     for i in tempList: 
      del i 

with open("location3", 'w') as final: 
    a = csv.writer(final, delimiter=',') 
    a.writerows(output) 

У меня есть два CSV-файлы, содержащие 15000 строк каждый, и я ищу, чтобы сравнить столбцы из каждого, и если они совпадают, сцепить конец второго CSV к концу первого. Любая помощь будет принята с благодарностью!

Спасибо!

+0

Pro: Работает с родными библиотеками и не имеет внешних зависимостей. Кон: Вы можете сделать это намного проще и быстрее с помощью Pandas (как указано ниже). Оба, сравнение и добавление (я думаю, это будет 3 или 4 строки кода) – Kelvin

ответ

2

Это должно быть более эффективным, таким образом:

import csv 
from collections import defaultdict 

with open("location1", 'r') as main: 
    csvMain = csv.reader(main) 
    mainList = list(csvMain) 

with open("location2", 'r') as anno: 
    csvAnno = csv.reader(anno) 
    annoList = list(csvAnno) 

output = [] 
annoMap = defaultdict(list) 

for annot in annoList: 
    tempList = annot[3:] # adapt this to the needed columns 
    annoMap[annot[2].lower()].append(tempList) # put these columns into the map at position of the column of intereset 

for full in mainList: 
    geneName = full[2].lower() 
    if geneName in annoMap: # check if matching column exists 
    output.extend(annoMap[geneName]) 

with open("location3", 'w') as final: 
    a = csv.writer(final, delimiter=',') 
    a.writerows(output) 

Это более эффективно, так как вам нужно перебирать каждый список только один раз. Поиск в словаре - это O (1) в среднем, поэтому вы в основном получаете линейный алгоритм.

+2

Это может помочь, если вы объясните * почему * ваши изменения делают его более эффективным. – Paul

+0

Красивая! Это было почти идеально, хотя оно только распечатывает отображенные значения в файл. Было легко исправить добавление как * полной * переменной, так и * annoMap [geneName] *, чтобы сделать одну длинную строку. Большое спасибо! –

1

Один простой способ - использовать библиотеку, такую ​​как Pandas. встроенные функции довольно эффективны.

Вы можете загрузить свой csv в dataframe с помощью pandas.read_csv(), а затем управлять ими с помощью функций pandas.

Например, вы можете использовать Pandas.merge() для объединения двух данных (например, двух ваших файлов csv) в определенном столбце, а затем отбросить тот, который вам не нужен.

Если у вас есть знание базы данных, логика здесь очень похожа.

0

Благодарим вас за помощь. Это был последний сценарий, который я использовал, подумал, что я опубликую его, чтобы помочь другим. Еще раз спасибо!

import csv 
from collections import defaultdict 

with open("location1", 'r') as main: 
    csvMain = csv.reader(main) 
    mainList = list(csvMain) 

with open("location2", 'r') as anno: 
    csvAnno = csv.reader(anno) 
    annoList = list(csvAnno) 

output = [] 
annoMap = defaultdict(list) 

for annot in annoList: 
    tempList = annot[3:] # adapt this to the needed columns 
    annoMap[annot[2].lower()].append(tempList) # put these columns into the map at position of the column of intereset 

for full in mainList: 
    geneName = full[2].lower() 
    if geneName in annoMap: # check if matching column exists 
    list = annoMap[geneName] 
    full.extend(list[0]) 
    output.append(full) 

with open("location3", 'w') as final: 
a = csv.writer(final, delimiter=',') 
a.writerows(output)