2014-07-22 4 views
0

У меня довольно большой файл (3 миллиона строк), причем каждая строка является отношением «человек к событию». Ultimate, я хочу проецировать эту двухстороннюю сеть на одномодовую, взвешенную сеть и записывать ее в файл CSV. Я использую NetworkX, и я проверил свой код на гораздо меньшем наборе данных образца, и он работает так, как должен. Однако, когда я масштабируюсь до своего фактического набора данных, мой компьютер просто увеличивает память, вращается и вращается, но не делает никакого прогресса.Двусторонняя проекция и запись в CSV с помощью NetworkX - как ускорить запись для обработки большого файла

Я использую машину AWS EC2 с 32 ГБ памяти.

После некоторого выборочного тестирования я уверен, что все вещи повесились на последнем шаге после того, как график был спроецирован, и он записывается в файл CSV. Я попытался разбить файл на куски, но потом у меня проблема с отсутствующим краем или правильное добавление edgeweights вместе. Но я думаю, что лучшим решением будет найти способ ускорить запись прогнозируемого графика в CSV.

Дополнительная информация о первоначальных данных: В некоторых мероприятиях есть только 1 человек, в то время как другие мероприятия посещают 5000 человек. Из-за этого будет создано огромное количество ребер (я предскажу ~ 50 М), созданных при сгибании двухпартийной сети в одномодовую сеть.

кода с использованием NetworkX для проекта двудольной сети и запись в формат CSV

# import modules 
import time 
import csv 
import networkx as nx 
from networkx.algorithms import bipartite 

startTime = datetime.datetime.now() 

# rename files 
infile = 'bipartite_network.csv' 
name_outfile = infile.replace('.csv', '_nameFolded.csv.') 
print 'Files renamed at: ' + str(datetime.datetime.now() - startTime) 

# load CSV into a dict 
with open(infile, 'rb') as csv_file: 
    rawData = list(csv.DictReader(csv_file)) 
print 'Files loaded at: ' + str(datetime.datetime.now() - startTime) 

# create edgelist for Name -x- Event relationships 
edgelist = [] 
for i in rawData: 
    edgelist.append(
    (i['Event'], 
    i['Name'])  
    ) 
print 'Bipartite edgelist created at: ' + str(datetime.datetime.now() - startTime) 

# deduplicate edgelist 
edgelist = sorted(set(edgelist)) 
print 'Bipartite edgelist deduplicated at: ' + str(datetime.datetime.now() - startTime) 

# create a unique list of Name and Event for nodes 
Event = sorted(set([i['Event'] for i in rawData])) 
Name = sorted(set([i['Name'] for i in rawData])) 
print 'Node entities deduplicated at: ' + str(datetime.datetime.now() - startTime) 

# add nodes and edges to a graph 
B = nx.Graph() 
B.add_nodes_from(Event, bipartite=0) 
B.add_nodes_from(Name, bipartite=1) 
B.add_edges_from(edgelist) 
print 'Bipartite graph created at: ' + str(datetime.datetime.now() - startTime) 

# create bipartite projection graph 
name_nodes, event_nodes = bipartite.sets(B) 
event_nodes = set(n for n,d in B.nodes(data=True) if d['bipartite']==0) 
name_nodes = set(B) - event_nodes 
name_graph = bipartite.weighted_projected_graph(B, name_nodes) 
print 'Single-mode projected graph created at: ' + str(datetime.datetime.now() - startTime) 

# write graph to CSV 
nx.write_weighted_edgelist(name_graph, name_outfile, delimiter=',') 
print 'Single-mode weighted edgelist to CSV: ' + str(datetime.datetime.now() - startTime) 

endTime = datetime.datetime.now() 
print 'Run time: ' + str(endTime - startTime) 

Использования панды Написать проецируемый Edgelist, но Missing Грани веса?

Я думал об использовании pandas для записи в name_graph в CSV. Будет ли это хорошим вариантом для ускорения написания в CSV-части процесса?

import pandas as pd 
df = pd.DataFrame(name_graph.edges(data=True)) 
df.to_csv('foldedNetwork.csv') 
+0

Глядя на источнике, похоже, функция записи не должна действительно быть слишком много борова памяти: см [здесь] (http://networkx.github.io/documentation/networkx-1.9/_modules/networkx/readwrite/edgelist.html#generate_edgelist) и [здесь] (http://networkx.github.io/documentation/networkx -1,9/_modules/NetworkX/чтение и запись/edgelist.html # write_edgelist). Все, кажется, использует генераторы вместо того, чтобы делать копии в памяти. Вы уверены, что у вас заканчивается память? – Marius

+0

@ Marius - Я не уверен, но я считаю, что это проблема. С другими меньшими образцами, которые я пробовал, все работает быстро (~ 1 мин), затем для записи CSV-файла требуется 10 + мин. –

+0

Pandas, несомненно, будет быстрее читать csv и, возможно, писать csv, стоит изучить этот вариант, см. Http://wesmckinney.com/blog/?p=543 и http://wesmckinney.com/blog/?p=278 , Dataframes могут принимать различные данные в качестве данных, вам нужно извлечь соответствующие данные из 'name_graph.edges (data = True)' в dict, ключи - это имена столбцов, значения - значения столбцов. 'edge' возвращает список кортежей, первые два значения - идентификаторы узлов, третий - атрибут атрибутов, вам нужно развернуть все это в плоский dict. – EdChum

ответ

1

Вот что я предложил на NetworkX-обсуждение списка рассылки:

import networkx as nx 

B = nx.Graph() 
B.add_edge('a',1) 
B.add_edge('a',2) 
B.add_edge('b',1) 
B.add_edge('b',2) 
B.add_edge('b',3) 
B.add_edge('c',3) 

nodes = ['a','b','c'] 
seen = set() 
for u in nodes: 
# seen=set([u]) # print both u-v, and v-u 
    seen.add(u) # don't print v-u 
    unbrs = set(B[u]) 
    nbrs2 = set((n for nbr in unbrs for n in B[nbr])) - seen 
    for v in nbrs2: 
     vnbrs = set(B[v]) 
     common = unbrs & vnbrs 
     weight = len(common) 
     print("%s, %s, %d"%(u,v,weight)) 

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

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