-1

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

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 的邻居。

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

4

1 回答 1

1

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

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

对于第一个任务,您可以使用to_dictpandas 函数将您的数据框转换为字典字典,然后根据它们的值是 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
于 2018-10-20T15:58:33.030 回答