[英]Loading very large RDF triples into iGraph -> Fast vertices lookup?
我需要将一个DBPedia图的子集加载到iGraph中,以便计算一些图形统计信息(例如节点中心性,......)。 我使用Redlands libRDF python库加载DBPedia三元组。 每个节点都与URI(唯一标识符)相关联。
我将图形加载到iGraph时遇到了一些麻烦。 这就是我做的:
1)读三线(主语,谓语,宾语)
2)使用以下算法获取或创建顶点(带属性)
def add_or_find_vertex (self, g, uri):
try:
return g.vs.find(name=uri)
except (KeyError, ValueError):
g.add_vertex(name=uri)
return g.vs.find(name=uri)
subjVertex = self.add_or_find_vertex(self.g, subject)
objVertex = self.add_or_find_vertex(self.g, object)
self.g.add_edge(subjVertex, objVertex, uri=predicate)
问题是我的脚本非常慢,我需要加载25M三倍。 每个节点都是唯一的,但在三重文件中可以找到几次。 因此,我需要在创建边缘之前执行查找。 你能告诉我“find”方法是否正在使用索引进行查找(Hashtable,...)? 顶点查找的复杂性是多少? 你会怎么做?
非常感谢你
已在这里回答。 为了完整起见,我也在这里复制我的答案:
顶点查找通常为O(| V |),因为默认情况下不对顶点属性建立索引 - 除了
name
vertex属性的索引。 但是,g.vs.find
仅在您执行此操作时才使用此索引:g.vs.find(url)
但如果执行此操作则不会:g.vs.find(name=url)
。 这是一种错误,因为索引可以在两种情况下使用。 还可以从邮件列表中查看昨天的帖子 。但请注意,igraph的数据结构针对静态图进行了优化,因此
g.add_vertex
(我认为你也使用g.add_edge
)也可能成为瓶颈。 在内部,igraph使用索引边缘列表来存储图形,并且每次变换图形时都必须重新构建索引,因此在可能的情况下批量执行顶点和边缘添加会更有效。既然你似乎已经有一个迭代器以
(subject, predicate, object)
形式产生图形的边缘,那么使用Graph.DictList
可以更容易一次构造图形,因为它还可以将顶点ID存储在name
属性,在有意义的批处理中添加边,以及从三元组中添加predicate
属性:>>> g = Graph.DictList(vertices=None, edges=({"source": subject, ... "target": object, "predicate": predicate} ... for subject, predicate, object in your_iterator))
Graph.DictList
在我的机器上以1.63秒的Graph.DictList
处理100000个预生成的随机三元组,所以我猜这会改善一些事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.