Я пишу класс, который наследует от DiGraph.py из пакета open source networkx в python.
В некотором методе в моем классе мне нужно искать узлы с определенными степенями (outdegrees или indegrees для ориентированного графа) и возвращать их.
Этот класс должен использоваться с проектом интеллектуального анализа данных\обработка естественного языка, который будет использоваться в чрезвычайно больших сетях. мне нужна быстрая реализация описанного метода (возвращаемый список узлов с определенной степенью или определенный по степени).
Есть пара вещей, которые уже определены в суперклассе:
1. метод network.outdegree()
:
возвращает словарь с node ключами и устаревшими значениями.
{'school': 4, 'middle school': 0, 'university': 0, 'commercial': 0, 'private': 5, 'institution': 2, 'high school': 0, 'college': 0, 'elementary school': 0, 'central': 0, 'company': 0, 'public': 3, 'bank': 2}
network.out_degree_iter()
<generator object out_degree_iter at 0x02EEB328>
Я не знаю, как использовать этот метод. Если кто-то может объяснить, как это используется, я буду благодарен.
3. У меня есть атрибут network.nodes, который является списком всех узлов в моей сети.
Вопрос: Я могу перебирать все узлы и возвращать их с outdegree 2, например, выполняя понимание списка в network.nodes, или я могу перебирать свой словарь и возвращать список узлов со значениями 2 или возможно, используйте out_degree_iter()
, который я не знаю, как это используется или как это отличается от итерации по элементам словаря в цикле for (для k, v в dict.iteritems())? Какой из них будет быстрее для очень большой сети узлов и ребер и ПОЧЕМУ?
Спасибо
Самый простой способ - использовать метод out_degree_iter() со списком, который вы предлагали. Вот как:
import networkx as nx
G=nx.DiGraph(nx.gnp_random_graph(1000,0.001))
t1=[n for n,k in G.out_degree_iter() if k==2
Самый быстрый способ требует доступа к внутренней структуре данных:
t2=[n for n,nbrs in G.succ.items() if len(nbrs)==2]
Для in-degree us in_degree_iter() и G.pred.items().
Вот некоторые тайминги
In [41]: %timeit t1=[n for n,k in G.out_degree_iter() if k==2]
1000 loops, best of 3: 368 us per loop
In [42]: %timeit s2=[n for n,nbrs in G.succ.items() if len(nbrs)==2]
1000 loops, best of 3: 198 us per loop
Итераторы лучше подходят для больших графов, потому что вы не создаете копию словаря. Как насчет чего-то подобного:
list_of_2 = []
for g in G.out_degree_iter():
if g[1]==2:
list_of_2.append(g[0])
Или
list_of_2 = map(lambda x:x[0],filter(lambda x:(x[1]==2),G.out_degree_iter()))