2016-03-07 34 views
2

我在網絡x中做了一些複雜的計算。計算涉及爲網絡中的每個節點反覆計算一些數量。正如這樣一個計算的例子,假設我們想要計算網絡中每個節點的平均鄰近度並將該值保存爲節點屬性。下面的代碼片段對我的作品:使用並行python來並行化網絡中的節點上的循環x

import networkx as nx 

G = nx.erdos_renyi_graph(10, 0.5) 

def ave_nbr_deg(node): 
    value = 0. 
    for nbr in G.neighbors(node): 
     value += G.degree(nbr) 
    G.node[node]['ave_nbr_deg'] = value/len(G.neighbors(node)) 

for node in G.nodes(): 
    ave_nbr_deg(node) 

print G.nodes(data = True) 

這給了我:

[(0, {'ave_nbr_deg': 5.4}), (1, {'ave_nbr_deg': 5.0}), (2, {'ave_nbr_deg': 5.333333333333333}), (3, {'ave_nbr_deg': 5.2}), (4, {'ave_nbr_deg': 5.6}), (5, {'ave_nbr_deg': 5.6}), (6, {'ave_nbr_deg': 5.2}), (7, {'ave_nbr_deg': 5.25}), (8, {'ave_nbr_deg': 5.5}), (9, {'ave_nbr_deg': 5.5})] 

這裏本身我有一個小疑問。對象G是在函數ave_nbr_deg之外創建的,我不知道該函數如何獲取其信息,即使我沒有聲明它是全局的。

現在,我想使用並行python模塊來使用我的系統上的所有核心進行此計算。做一些改變上面的代碼後,我得到了下面的代碼:

import networkx as nx 
import pp 

G = nx.erdos_renyi_graph(10, 0.5) 

def ave_nbr_deg(node): 
    value = 0. 
    for nbr in G.neighbors(node): 
     value += G.degree(nbr) 
    G.node[node]['ave_nbr_deg'] = value/len(G.neighbors(node)) 

job_server = pp.Server(ppservers =()) 

print "Starting pp with", job_server.get_ncpus(), "workers" 

for node in G.nodes(): 
    job_server.submit(ave_nbr_deg, args = (node,))() 

print G.nodes(data = True) 

但它返回以下錯誤:

An error has occured during the function execution 
Traceback (most recent call last): 
    File "/usr/local/lib/python2.7/dist-packages/ppworker.py", line 90, in run 
    __result = __f(*__args) 
    File "<string>", line 5, in ave_nbr_deg 
NameError: global name 'G' is not defined 

我試過各種事情,包括模塊名稱nx在提交等。但是,我沒有得到什麼確切的問題。不幸的是,documentation of smp太短,無法解決這個問題。如果有人能幫助我,我將非常感激。

在此先感謝

回答

1

要回答你的第一個問題:Python的首先查找本地名稱空間中的變量。如果它沒有在那裏找到它們,那麼它將移到父命名空間並在那裏尋找它。這就是它如何找到G,即使G不是在本地聲明的。下面是關於變量作用域的詳細信息:Python scoping

可能有兩種解決方案:

1 - 通過G作爲參數傳遞給功能ave_nbr_deg,例如

for node in G.nodes(): 
    job_server.submit(ave_nbr_deg, args = (node,G))() 

2 - 申報克,在提交ARGS一個全局變量(從並行Python文檔)

submit(self, func, args=(), depfuncs=(), modules=(), 
     callback=None, callbackargs=(), group='default', globals=None) 
Submits function to the execution queue 

func - function to be executed 
args - tuple with arguments of the 'func' 
depfuncs - tuple with functions which might be called from 'func' 
modules - tuple with module names to import 
callback - callback function which will be called with argument 
     list equal to callbackargs+(result,) 
     as soon as calculation is done 
callbackargs - additional arguments for callback function 
group - job group, is used when wait(group) is called to wait for 
jobs in a given group to finish 
globals - dictionary from which all modules, functions and classes 
will be imported, for instance: globals=globals() 

在這種情況下,調用下面應該工作:

for node in G.nodes(): 
    job_server.submit(ave_nbr_deg, args = (node,G), globals=globals())() 
+0

不幸,這兩個都不起作用。特別是,它們爲節點屬性提供空字典。而且,在我看來,通過整個G來實現每個節點的功能實際上會降低性能。 – Peaceful