我有一个 networkx 图对象,它是加权的和无向的。我正在尝试使用 Adamic Adar 索引为每个节点预测 10 个新链接。Networkx 中的函数adamic_adar_index 返回元组的生成器,其格式为(nodeid1, nodeid2,adamic_adar_index)。我不熟悉 Python 中的生成器。我想要做的是按 nodeid1 对生成器进行分组,并为 nodeid1 返回最大的 10 个索引。
这是我的代码,其中“coauthor”是网络对象,“preds”是生成器。数据文件在这里https://www.dropbox.com/s/hyr1hgjs4yt03x2/coauthor.csv?dl=0
import csv
import networkx as nx
g = nx.read_weighted_edgelist("coauthor.csv", delimiter='\t', encoding='utf-8')
coauthor = nx.read_weighted_edgelist("coauthor.csv", delimiter='\t', encoding='utf-8')
preds = nx.adamic_adar_index(coauthor)
Run Code Online (Sandbox Code Playgroud)
看一看 heapq.nlargest 它接受一个迭代并返回该迭代中的 n 个最大的东西。由于我没有您的合著者列表,我将使用空手道图。不是立即查看所有非边(如默认情况下 adamic_adar_index 所做的那样),我将遍历 G 中的每个节点 u 并对 u 的所有非邻居执行此操作
import networkx as nx
import heapq
def nonedges(G,u): #a generator with (u,v) for every non neighbor v
for v in nx.non_neighbors(G, u):
yield (u, v)
G = nx.karate_club_graph()
for u in G.nodes_iter():# you may want to check that there will be at least 10 choices.
preds = nx.adamic_adar_index(G,nonedges(G,u))
tenlargest = heapq.nlargest(10, preds, key = lambda x: x[2])
print tenlargest
Run Code Online (Sandbox Code Playgroud)
警告:如果您在这里不小心,您描述的算法中存在一个错误:对于节点 1,您可能会发现某些元组返回为 (1, 2, 3.2), (1, 3, 0.3), ( 4, 1, 100)。根据您描述分组的方式,您会错过 (4,1) 对。我的示例检查每对两次以避免这种情况。您可以通过一些努力来消除这种重复的计算机工作。
生成器和迭代器密切相关。有关迭代器的更多信息,请访问https://docs.python.org/2/glossary.html#term-iterator(您也可以在该页面上找到生成器)。您可以将其视为一个列表,但有关于您如何访问它的规则。每次查看它时,都会得到下一个元素。一旦你查看了元素,它就会从迭代器中移除。您一次只能从迭代器中获取一件事。在计算机内存中,它不必保存整个事物(它会在需要时生成下一个元素)。例如,您可以看到我在循环中使用了迭代器而不是 G.nodes()。这意味着计算机永远不必将 G 中的所有节点都保存在其内存中。
for u in G.nodes_iter():
Run Code Online (Sandbox Code Playgroud)
相对
for u in G.nodes()
Run Code Online (Sandbox Code Playgroud)