我有大约1000个类别'它覆盖了我的边缘。我使用属性指定这些类别:
g.es[0]["$cat1"]=True
一条边可以属于多个类别。
问题是,这会导致我的所有其他边缘,即使它们与类别1无关,也无法获得属性$cat1=None
。
所以基本上即使我的边缘是单个类别的一部分,它也会有999个其他属性,例如$catN=None
。
我需要能够将每个类别(包括它的所有成员节点和边缘)提取到一个单独的子图中。现在,我只是遍历所有边缘,查看$catN = True
的位置,并将这些边和节点放入新图中。
$catN = True
,但数千个冗余$catN = None
。答案 0 :(得分:0)
是否有必要将每条边的类别存储为边属性?如果您的图形不会被突变(即您不会从图形中删除边缘),您可以简单地使用将类别ID映射到边缘ID的外部Python dict - 然后您可以使用单个字典查找来获取每个类别的成员。如果你还需要快速告诉边缘属于哪个类别,你还需要反向映射,所以也许最好创建一个单独的“双向映射”类并分别维护映射的两面:
from collections import defaultdict
class CategoryMapping(object):
def __init__(self):
self.category_to_members = defaultdict(set)
self.member_to_categories = defaultdict(set)
def add(self, category, member):
self.category_to_members[category].add(member)
self.member_to_categories[member].add(category)
def remove(self, category, member):
self.category_to_members[category].discard(member)
self.member_to_categories[member].discard(category)
def categories_of(self, member):
return self.member_to_categories[member]
def members_of(self, category):
return self.category_to_member[category]
修改:如果有时会从图表中删除边缘,您可以为其id
边缘属性中的每条边分配唯一ID,然后在{{1}中使用这些ID }。唯一的问题是按属性的边缘查找是O(n)操作,其中n是边数。为了缓解这种情况,您还可以创建边缘ID到索引映射类。这个类可以有一个CategoryMapping
方法,每当你从图中删除边时,你必须用删除边的旧ID调用它,并且它应该相应地更新内部ID到索引的映射。 (可悲的是,igraph没有边缘的特殊id类属性,即使它以这种方式处理顶点对象的edges_removed()
属性,因此你可以按名称实现顶点的O(1)查找。你可以利用这样一个事实,即如果 k 删除边缘,索引更小,那么边缘 i 的索引将成为 ik 比原始图中的 i 。