For 循环到 python 中的邻接矩阵

For loops to a adjacency matrix in python

我需要对 python 中的邻接矩阵执行循环。我的目标是在矩阵中找到一阶和二阶邻居。我用pysal queen contiguity做了矩阵。 1 是邻居,0 不是 neighbour.Code:

import pandas as pd
import pysal as ps

w = ps.queen_from_shapefile('test.shp')
Wmatrix, ids = w.full()
Wmatrix
W_DataFrame = pd.DataFrame(Wmatrix,columns=["A","B","C","D","E","F",
                                                   "G","H","I","J","K","L",
                                                   "N","M"],
                                        index=["A","B","C","D","E","F",
                                                   "G","H","I","J","K","L",
                                                   "N","M"])

print W_DataFrame

矩阵为:

    A    B    C    D    E    F    G    H    I    J    K    L    N    M
A  0.0  0.0  1.0  0.0  0.0  0.0  1.0  0.0  0.0  0.0  1.0  0.0  0.0  0.0
B  0.0  0.0  0.0  0.0  1.0  0.0  1.0  0.0  1.0  0.0  0.0  0.0  0.0  0.0
C  1.0  0.0  0.0  1.0  0.0  0.0  0.0  1.0  0.0  1.0  1.0  1.0  0.0  1.0
D  0.0  0.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0  1.0  0.0  0.0  1.0  0.0
E  0.0  1.0  0.0  0.0  0.0  0.0  1.0  0.0  1.0  0.0  1.0  0.0  0.0  0.0
F  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  1.0  0.0  0.0  1.0  0.0
G  1.0  1.0  0.0  0.0  1.0  0.0  0.0  0.0  0.0  0.0  1.0  0.0  0.0  0.0
H  0.0  0.0  1.0  0.0  0.0  0.0  0.0  0.0  1.0  0.0  1.0  1.0  0.0  0.0
I  0.0  1.0  0.0  0.0  1.0  0.0  0.0  1.0  0.0  0.0  1.0  1.0  0.0  0.0
J  0.0  0.0  1.0  1.0  0.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0  1.0  1.0
K  1.0  0.0  1.0  0.0  1.0  0.0  1.0  1.0  1.0  0.0  0.0  0.0  0.0  0.0
L  0.0  0.0  1.0  0.0  0.0  0.0  0.0  1.0  1.0  0.0  0.0  0.0  0.0  1.0
N  0.0  0.0  0.0  1.0  0.0  1.0  0.0  0.0  0.0  1.0  0.0  0.0  0.0  0.0
M  0.0  0.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0  1.0  0.0  1.0  0.0  0.0

例如: 位置A有3个第一邻居(C,H,K),B是G的邻居,C是B的邻居。

如何使用for循环构建列表字典? 如: {'A': ['C','H','K','G','B'] }

看起来你实际上有两个任务:

  1. 将 pandas 数据帧转换为显示一阶邻居的字典
  2. 将该字典转换为显示二阶邻居的字典

对于第一个任务,您可以使用 to_dict pandas 函数将您的数据框转换为字典字典,然后根据它们的值是 0.0 还是 1.0 过滤子字典.以您的数据框 df 为例:

d = {}
for k, subdict in df.to_dict().items():
    neighbours = []
    for k2, value in subdict.items():
        if value:
            neighbours.append(k2)
    d[k] = neighbours

现在 d 是一个包含每个键的一阶邻居的字典:

print(d)
{'A': ['C', 'G', 'K'],
 'B': ['E', 'G', 'I'],
 'C': ['A', 'D', 'H', 'J', 'K', 'L', 'M'],
 'D': ['C', 'J', 'N'],
 'E': ['B', 'G', 'I', 'K'],
 'F': ['J', 'N'],
 'G': ['A', 'B', 'E', 'K'],
 'H': ['C', 'I', 'K', 'L'],
 'I': ['B', 'E', 'H', 'K', 'L'],
 'J': ['C', 'D', 'F', 'N', 'M'],
 'K': ['A', 'C', 'E', 'G', 'H', 'I'],
 'L': ['C', 'H', 'I', 'M'],
 'N': ['D', 'F', 'J'],
 'M': ['C', 'J', 'L']}

为了将其转换为也显示二阶邻居,您应该遍历每个键的值,查找每个值的邻居并将它们添加到原始值列表中。

def find_second_order_neighbours(d):
    d2 = {} 
    for k, neighbours in d.items(): # loop over the dictionary
        new_neighbours = set(neighbours) # create a temporary set to store all second order neighbours
        for neighbour in neighbours: # loop over the original neighbours
            new_neighbours = (new_neighbours | set(d[neighbour])) - {k} # add all second order neighbours ignoring duplicates (and making sure k is not its own neighbour)
        d2[k] = list(new_neighbours) # update the dictionary to return
    return d2

print(find_second_order_neighbours(d))
{'A': ['E', 'K', 'G', 'C', 'L', 'J', 'I', 'H', 'M', 'D', 'B'],
 'B': ['E', 'G', 'K', 'L', 'A', 'I', 'H'],
 'C': ['N', 'E', 'K', 'G', 'L', 'A', 'J', 'I', 'H', 'M', 'F', 'D'],
 'D': ['N', 'K', 'C', 'L', 'A', 'J', 'H', 'M', 'F'],
 'E': ['K', 'G', 'C', 'L', 'A', 'I', 'H', 'B'],
 'F': ['N', 'C', 'J', 'M', 'D'],
 'G': ['E', 'K', 'C', 'A', 'I', 'H', 'B'],
 'H': ['E', 'K', 'G', 'C', 'L', 'A', 'J', 'I', 'M', 'D', 'B'],
 'I': ['E', 'K', 'G', 'C', 'L', 'A', 'H', 'M', 'B'],
 'J': ['N', 'K', 'C', 'L', 'A', 'H', 'M', 'F', 'D'],
 'K': ['E', 'G', 'C', 'L', 'A', 'J', 'I', 'H', 'M', 'D', 'B'],
 'L': ['E', 'K', 'C', 'A', 'J', 'I', 'H', 'M', 'D', 'B'],
 'N': ['C', 'J', 'M', 'F', 'D'],
 'M': ['N', 'K', 'C', 'L', 'A', 'J', 'I', 'H', 'D', 'F']}

额外

如果您不仅对二阶邻居(三阶、四阶等)感兴趣,还可以重复调用 find_second_order_neighbours 函数来查找 n 阶邻居,例如所以:

def find_n_order_neighbours(n, d):
    while n > 1:
        d = find_second_order_neighbours(d)
        n -= 1
    return d