2017-08-03 51 views
0

编辑:现在看好正如标题所说,我试图让计算数量的功能如何,每个节点蟒蛇:找到输入到输出的路径在networkX

计算的“循环路径”#网络中任何节点的“信号路径”。节点的信号路径是从多个输入中的一个输入到该节点所属的多个输出之一的路径。我正在使用一个已经叫做all_simple_paths的算法,它是一个返回从输入到输出的每条路径的生成器。

然而,即使我的代码看起来正确,我得到不正确的结果。这里的功能:

def signal_path_counter(G, inputs, outputs, node): 
    c = 0 
    paths = [] 
    for out in outputs: 
     for i in inputs: 
      for path in all_simple_paths(G, i, out): 
       paths.append(path) 
    for path in paths: 
     for n in path: 
      if(node == n): 
       c += 1 
    return c 

这里的输入数据:

import networkx as nx 
import matplotlib.pyplot as plt 
G=nx.DiGraph() 
molecules = ["CD40L", "CD40", "NF-kB", "XBP1", "Pax5", "Bach2", "Irf4", "IL-4", "IL-4R", "STAT6", "AID", "Blimp1", "Bcl6", "ERK", "BCR", "STAT3", "Ag", "STAT5", "IL-21R", "IL-21", "IL-2", "IL-2R"] 
Bcl6 = [("Bcl6", "Bcl6"), ("Bcl6", "Blimp1"), ("Bcl6", "Irf4")] 
STAT5 = [("STAT5", "Bcl6")] 
IL_2R = [("IL-2R", "STAT5")] 
IL_2 = [("IL-22", "IL-2R")] 
BCR = [("BCR", "ERK")] 
Ag = [("Ag", "BCR")] 
CD40L = [("CD40L", "CD40")] 
CD40 = [("CD40", "NF-B")] 
NF_B = [("NF-B", "Irf4"), ("NF-B", "AID")] 
Irf4 = [("Irf4", "Bcl6"), ("Irf4", "Pax5"), ("Irf4", "Irf4"), ("Irf4", "Blimp1")] 
ERK = [("ERK", "Bcl6"), ("ERK", "Blimp1"), ("ERK", "Pax5")] 
STAT3 = [("STAT3", "Blimp1")] 
IL_21 = [("IL-21", "IL-21R")] 
IL_21R = [("IL-21R", "STAT3")] 
IL_4R = [("IL-4R", "STAT6")] 
STAT6 = [("STAT6", "AID"), ("STAT6", "Bcl6")] 
Bach2 = [("Bach2", "Blimp1")] 
IL_4 = [("IL-4", "IL-4R")] 
Blimp1 = [("Blimp1", "Bcl6"), ("Blimp1", "Bach2"), ("Blimp1", "Pax5"), ("Blimp1", "AID"), ("Blimp1", "Irf4")] 
Pax5 = [("Pax5", "Pax5"), ("Pax5", "AID"), ("Pax5", "Bcl6"), ("Pax5", "Bach2"), ("Pax5", "XBP1"), ("Pax5", "ERK"), ("Pax5", "Blimp1")] 
edges = Bcl6 + STAT5 + IL_2R + IL_2 + BCR + Ag + CD40L + CD40 + NF_B + Irf4 + 
ERK + STAT3 + IL_21 + IL_21R + IL_4R + STAT6 + Bach2 + IL_4 + Blimp1 + Pax5 
G.add_nodes_from(molecules) 
G.add_edges_from(edges) 
sources = ["Ag", "CD40L", "IL-2", "IL-21", "IL-4"] 
targets = ["XBP1", "AID"] 

输入网络here的视觉表现。

函数调用给出的0不正确的结果:

print(signal_path_counter(G, sources, targets, "IL-2R")) 
+0

所以,不,如果你看一下图形的视觉表现,在源和目标仅仅是输入和输出节点,我们用它来计算出路径的X数量从任何输入到任何输出来获得。 IL-2R是一个正在开发中的节点,我想得到IL-2R在这些输入到输出路径中出现次数的计数器。这个数字就是我在函数中返回的值。 – witcheR

回答

1

你的错字是在这一行:

IL_2 = [("IL-22", "IL-2R")] 

应该

IL_2 = [("IL-2", "IL-2R")] 

有有些事情可以与你的合作完成让它更“pythonic”。遍历多个组合可以更干净地使用this approach来完成,其中将取代遍历out和过i

for input, output in itertools.product(inputs, outputs): 
    for path in all_simple_paths(G, input, output): 
     paths.append(...) 

此外而不是建立路径,然后通过paths循环测试,如果该节点是在它,做了测试,而不是直接追加到paths

for input, output in itertools.product(inputs, outputs): 
    for path in all_simple_paths(G, input, output): 
     if node in path: 
      c += 1 

即使这个代码,我认为这可能使用Counter进行清洁。基本上,如果你曾经做variable += 1,或追加元素的列表迭代时,往往是一个“更Python”的方式来做到这一点。

我关心这个算法如何为更大的网络规模。找到所有的路径是昂贵的。这可能是更好地从node开始,建立从nodeoutputs所有路径和所有路径从inputsnode。然后将每个路径转换为一组[转换为集合使下一步更快]。然后通过进出的路径,看看他们是否有任何交集。如果没有,那么你已经通过node

这会显著减少你最终不得不考虑路径的数量(以及可能的路径的长度为好)。

+0

谢谢你有关如何优化这个想法。现在,我正在写一篇只能使用2个这种大小的网络的文章,所以幸运的是我的效率并不是一个大问题。 – witcheR

+0

后续问题,我需要为每个节点计算的另一个值是“反馈循环”,这意味着节点出现在循环路径中的次数。有没有内置的算法呢? – witcheR

+0

我需要更多地了解“循环路径”究竟是什么。我可以想到一些可能的定义... – Joel