У меня довольно большой файл (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')
Глядя на источнике, похоже, функция записи не должна действительно быть слишком много борова памяти: см [здесь] (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
@ Marius - Я не уверен, но я считаю, что это проблема. С другими меньшими образцами, которые я пробовал, все работает быстро (~ 1 мин), затем для записи CSV-файла требуется 10 + мин. –
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