4

私は、それぞれのノードがkのいずれかのタイプである無向ネットワークを持っています。各ノード私はのために、ノード私はがそれぞれのタイプを持っている隣人の数を計算する必要があります。numgpyでedgelistからの "neigborhood"の値を累積します

今はエッジがノードのインデックスであるエッジグリストでエッジを表現しています。ノードはn x kの行列で表されます。各列はノードタイプを表します。ノードのタイプがkの場合、kカラムの値は1、そうでない場合は0です。

ここに私の現在のコードがありますが、それは正しいが、遅すぎる。

# example nodes and edges, both typically much longer 
nodes = np.array([[0, 0, 1], 
        [0, 1, 0],      
        [1, 0, 0]]) 
edges = np.array([[0, 1], 
        [1, 2]]) 

neighbors = np.zeros_like(nodes) 

for i, j in edges: 
    neighbors[i] += nodes[j] 
    neighbors[j] += nodes[i] 

私はこのforループを避けることができる賢明なnumpyがありますか?これを行う最善の方法が隣接行列である場合は、それも許容されます。

+2

なぜ '隣人[I] =ノード[j]を'? – HYRY

+0

申し訳ありませんが、 '='はタイプミスでした。 '+ =' – fgregg

+0

これは 'numpy.bincount()'を使うことができます。 – HYRY

答えて

1

あなたは、単にnp.add.at使用することができます -

out = np.zeros_like(nodes) 
np.add.at(out, edges[:,0],nodes[edges[:,1]]) 
np.add.at(out, edges[:,1],nodes[edges[:,0]]) 
2

私が正しくあなたの質問を理解していれば、numpy_indexedパッケージ(免責事項:私はその作者だが)これに迅速かつエレガントな解決策があります。一般的には

# generate a random example graph 
n_edges = 50 
n_nodes = 10 
n_types = 3 
edges = np.random.randint(0, n_nodes, size=(n_edges, 2)) 
node_types = np.random.randint(0, 2, size=(n_nodes, n_types)).astype(np.bool) 

# Note; this is for a directed graph 
s, e = edges.T 
# for undirected, add reversed edges 
s, e = np.concatenate([edges, edges[:,::-1]], axis=0).T 
import numpy_indexed as npi 
node_idx, neighbor_type_count = npi.group_by(s).sum(node_types[e]) 

を、jagged-を含むグラフ、またはアルゴリズムの操作グループ化操作を使用して効率的かつエレガントに表現することができます。