2013-05-06 2 views
0

Я анализирую сетевые и семантические значения твитов, которые я скачал по заданному предмету и геолокации, используя двудольный граф.Оптимизация скрипта индексирования для двудольного графика

Используя Python, я создаю файл .net, содержащий 2 набора узлов и ребер. Этот файл представляет собой объединение файлов, которые я создал отдельно: два набора вершин и краев. Проблема заключается в создании компонента Edges файла .net.

У меня есть 3 файла:

  • tweeterers.csv с отправителями/tweeterers ("номер/ID" и "имя")
  • words.csv, семантическими тегами/словами Я извлек из твитов. Формат - это «номер/идентификатор» и «имя», с «числом», начиная с последнего «числа» указанного файла. От 0 до 6 слов в строке
  • Names_Text_full_clean.csv, с твитерами и словами. Каждая строка содержит 1 имя твитера и от 0 до 6 слов. Этот файл даст мне связь между твитерами и словами для графика.

Я в основном читаю каждый твитер, читаю слово, читаю, если есть ассоциация. Если да, я пишу ассоциацию (это край). Это тройной цикл. Это очень медленно с сетями среднего размера: сеть с ~ 650 узлами и ~ 18000 ребер заняла у меня почти 2 дня на двухъядерном процессоре Mac Mini 2.7GHz.

Любая помощь, чтобы ускорить его, будет высоко оценена!

Ниже приведен код:

import csv # csv library is to handle csv files 

# open the twetterers file and make it available in 'reader1' 
file_read1 = open('tweeterers.csv', 'rU') 
    reader1 = csv.reader(file_read1) 

# open the file for writing and make it available in 'writer' 
file_write=open('edges.csv', 'wb') 
writer=csv.writer(file_write) 


for sender in reader1: 
    file_read2 = open('words.csv', 'rU') 
    reader2 = csv.reader(file_read2) 
    for word in reader2: 
     file_read = open('Names_Text_full_clean.csv', 'rU') 
     reader = csv.reader(file_read) 
     for match in reader: 
      for elem in range (1,len(match)): 
       if sender[1] == match [0]: 
        if word [1] == match [elem]: 
         a = sender[0],word[0] 
         writer.writerow(a) 
         print "I wrote a record: it's: ",a 

file_read.close() 
file_read1.close() 
file_read2.close() 
file_write.close() 
+0

Вы действительно печатаете результаты 'print 'Я написал запись: это:", a'? Если вы, вероятно, должны удалить это, это, безусловно, ускорит процесс. – Brad

+0

Конечно, Брэд.Это было сделано только для целей отладки. Спасибо за ваш комментарий! – timeitself

ответ

0

Используйте словари. Например, первым шагом будет чтение Names_Text_full_clean.csv только один раз и сохранение результата в словаре, индексированном по match[0]. Поскольку может быть несколько раз то же самое match[0], вам нужно сохранить в качестве значения список, возможно, нескольких объектов match.

import collections 
by_sender = collections.defaultdict(list) 
file_read = open('Names_Text_full_clean.csv', 'rU') 
reader = csv.reader(file_read) 
for match in reader: 
    by_sender[match[0]].append(match) 

Тогда в вложенных циклов, вы можете заменить

for match in reader: 
     if sender[1] == match [0]: 

со следующей петлей, которая, вероятно, сотни раз меньше:

for match in by_sender[sender[1]]: 

Дальнейшая оптимизация будет не магазин match в виде списка by_sender[match[0]], но для хранения set(match[1:]). Действительно, вы будете смотреть только в том случае, если конкретная запись (word[1] в этом случае) равна любому из элементов в match[1:]. Вместо того, чтобы зацикливать, чтобы понять это, это можно сделать только с word[1] in my_set.

Это, вероятно, достаточно, но «конечная цель» состояла бы в том, чтобы прочитать все три файла только один раз. Вы храните содержимое двух файлов в некоторых подходящих словарях и выполняете поиск в словах только при прохождении через третий файл (или «набор запросов», которые также очень быстры).

+0

Armin, я применил предложенные вами изменения, введя словарь для описания результатов, прочитанных в файле Names_Text_full_clean.csv и замены одного из циклов. Я пошел от ~ 2 дней до менее 1 минуты (тот же набор данных). Большое спасибо! – timeitself

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