簡體   English   中英

來自2D陣列的Numpy- get鄰居矩陣

[英]Numpy- get neighbors matrix from 2D array

我有一個無向圖,由下式給出:

A,B
A,C
A,F
B,D
C,D
C,F
E,D
E,F

我需要將其轉換為矩陣N,其中

N[x,y] = 1 if x is neighbor of y (like A and B) and 0 if not

最快的方法是什么?

NOTA圖表存儲為numpy字符串數組:

array([['A', 'B'],
       ['A', 'C'],
       ['A', 'F'],
       ['B', 'D'],
       ['C', 'D'],
       ['C', 'F'],
       ['E', 'D'],
       ['E', 'F']], 
      dtype='|S4')

預期產量:

   A B C D E F
A  1 1 1 0 0 1
B  1 1 0 1 0 0 
C  1 0 1 1 0 1
D  0 1 1 1 1 0
E  0 0 0 1 1 1 
F  1 0 1 0 1 1

謝謝

使用networkx

A=nx.Graph()
for x in a:
    A.add_edge(x[0],x[1])
ad =nx.adjacency_matrix(A)

matrix([[ 0.,  1.,  1.,  0.,  0.,  1.],
        [ 1.,  0.,  0.,  0.,  1.,  1.],
        [ 1.,  0.,  0.,  0.,  1.,  0.],
        [ 0.,  0.,  0.,  0.,  1.,  1.],
        [ 0.,  1.,  1.,  1.,  0.,  0.],
        [ 1.,  1.,  0.,  1.,  0.,  0.]])

建議使用fill_diagonal來獲取預期輸出中的自鏈接:

np.fill_diagonal(ad,1)

matrix([[ 1.,  1.,  1.,  0.,  0.,  1.],
        [ 1.,  1.,  0.,  1.,  0.,  0.],
        [ 1.,  0.,  1.,  1.,  0.,  1.],
        [ 0.,  1.,  1.,  1.,  1.,  0.],
        [ 0.,  0.,  0.,  1.,  1.,  1.],
        [ 1.,  0.,  1.,  0.,  1.,  1.]])

這是一種NumPythonic方法 -

# Tag each string with a numeric ID based on the uniqueness among other strings
_,ID = np.unique(graph,return_inverse=True)
M = ID.reshape(graph.shape)

# Consider each row of numeric IDs as an indexing tuple of a 2D array.
# Calculate the linear indices corresponding to each tuple.
n = M.max()+1
idx1 = M[:,0]*(n) + M[:,1]
idx2 = M[:,1]*(n) + M[:,0]

# Setup output array with 1s on the diagonal.
out = np.eye(n,dtype=int)

# Put 1s at places specified by the earlier computed pairs of linear indices
np.put(out,[idx1,idx2],1)

樣本輸入,輸出 -

In [93]: graph
Out[93]: 
array([['A', 'B'],
       ['A', 'C'],
       ['A', 'F'],
       ['B', 'D'],
       ['C', 'D'],
       ['C', 'F'],
       ['E', 'D'],
       ['E', 'F']], 
      dtype='|S4')

In [94]: out
Out[94]: 
array([[1, 1, 1, 0, 0, 1],
       [1, 1, 0, 1, 0, 0],
       [1, 0, 1, 1, 0, 1],
       [0, 1, 1, 1, 1, 0],
       [0, 0, 0, 1, 1, 1],
       [1, 0, 1, 0, 1, 1]])

運行時測試

本節基本上比較了迄今為止列出的所有方法(在這篇文章和其他帖子中)解決案例的表現。

定義功能 -

def networkx_based(a): #@atomh33ls's solution code
    A=nx.Graph()
    for x in a:
        A.add_edge(x[0],x[1])
    return nx.adjacency_matrix(A)

def vectorize_based(data): # @plonser's solution code
    ord_u = np.vectorize(lambda x: ord(x)-65)
    s = ord_u(data)
    res = np.zeros((s.max()+1,s.max()+1),dtype=int)
    res[s[:,0],s[:,1]] = 1
    res_sym = res + res.T
    np.fill_diagonal(res_sym,1)
    return res_sym

def unique_based(graph): #solution from this post
    _,ID = np.unique(graph,return_inverse=True)
    M = ID.reshape(graph.shape)
    n = M.max()+1
    idx1 = M[:,0]*(n) + M[:,1]
    idx2 = M[:,1]*(n) + M[:,0]
    out = np.eye(n,dtype=int)
    np.put(out,[idx1,idx2],1)
    return out

計時 -

In [321]: N = 1000

In [322]: arr = np.random.randint(65,90,(N,2))

In [323]: graph = np.array([map(chr,a) for a in arr],dtype='S4')

In [324]: %timeit networkx_based(graph)
100 loops, best of 3: 3.79 ms per loop

In [325]: %timeit vectorize_based(graph)
1000 loops, best of 3: 760 µs per loop

In [326]: %timeit unique_based(graph)
1000 loops, best of 3: 405 µs per loop

在純粹的numpy我會做類似的事情

import numpy as np

data = np.array([['A', 'B'],
         ['A', 'C'],
         ['A', 'F'],
         ['B', 'D'],
         ['C', 'D'],
         ['C', 'F'],
         ['E', 'D'],
         ['E', 'F']], dtype='|S4')

# define vectorized mapping from letters to integers
ord_u = np.vectorize(lambda x: ord(x)-65)

# map entities of data to integer
s = ord_u(data)

# initialize the matrix
res = np.zeros((s.max()+1,s.max()+1))

# use advanced indexing for calculating the matrix
res[s[:,0],s[:,1]] = 1

# symmetrize the matrix
res_sym = res + res.T
np.fill_diagonal(res_sym,1)

res_sym
#array([[ 1.,  1.,  1.,  0.,  0.,  1.],
#       [ 1.,  1.,  0.,  1.,  0.,  0.],
#       [ 1.,  0.,  1.,  1.,  0.,  1.],
#       [ 0.,  1.,  1.,  1.,  1.,  0.],
#       [ 0.,  0.,  0.,  1.,  1.,  1.],
#       [ 1.,  0.,  1.,  0.,  1.,  1.]])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM