эффективность Pyraph Networkx Digraph с миллионом строк - PullRequest
0 голосов
/ 11 мая 2018

У меня есть текст с миллионами строковых линий, каждая из которых похожа на этот формат:

#2851= TITLE('object','attribute',#2847,#2848,#2849,#2850);

Я сопоставляю его Диаграмму направленности с помощью networkx, чтобы получить все узлы и ребра, используя:

def Digraph_path(txt):
  G=nx.DiGraph()
  for l in txt:
    res = re.findall("#\d{3,10}",l)
    for num in res[1:]:
        G.add_edge(res[0],num)
  return G

Из-за количества строк в текстовом формате, процесс ниже занимает много времени.Я хочу сделать это более эффективным.Полезное объяснение этого процесса заключается в том, что сначала у меня есть элементы obj, каждый из которых имеет список «родителей», связанных с ним, поэтому сначала я использую predecessors и расширяю наш object_num_sets.

* 1011.* Природа информационной структуры в txt требует от нас этого.

После этого я нахожу детей, внуков и т. Д. Вплоть до иерархии,

* 1016.* genA -> genB -> genC -> genD -> genE -> genF

каждый раз, расширяя мой массив этими числами, поэтому в конце каждый элемент obj вмассив находится во вложенном списке со ВСЕМ его «семейства» из txt.

 for obj in matrix:
    idx = matrix.index(obj)

    for num in obj:
      object_num_sets[idx].append(num)
      genA = list( Digraph.predecessors(num) )
      object_num_sets[idx].extend(genA)

      for child in genA:
        genB = list( Digraph.successors(child) ) #we find further children

      #our initial obj number has parents, and they have children among 
      #which is also obj itself, so obj has "cousins", but we do not want to
      #repeat obj twice in the same list so we find it and remove it:
        for obj in matrix:
          if obj[0] in genB:
            genB.remove(obj[0]) #remove duplicate #'s
        object_num_sets[idx].extend(genB)

        for childB in genB:
          genC = list( Digraph.successors(childB) )
          object_num_sets[idx].extend(genC)

          for childC in genC:
            gen = list( Digraph.successors(childC) )
            object_num_sets[idx].extend(bnei_ninim)

            for childD in genD:
              genE = list( Digraph.successors(childD) )
              object_num_sets[idx].extend(genE)

              for childE in genE:
                genF = list( Digraph.successors(childE) )
                object_num_sets[idx].extend(genF)

Проблемы:

  1. как мы можем использовать networkx здесь более эффективно, учитывая, что мы не хотим повторять какие-либо числа, но мы также не хотим использовать только successors, потому что у нас есть один экземпляр, где мы хотим найти «двоюродных братьев и сестер» и поэтому сначала используем predecessors ...так что это не просто вопрос «каждая ветвь дерева»
  2. мы можем использовать yield вместо returnкаким-то образом ускорить процесс?
  3. В чем разница между списками и генераторами?Из того, что я могу сказать, генераторы не делают одно и то же, потому что после каждого цикла они перестают существовать частично или полностью, в зависимости от уровня вложенного цикла ...?
...