首页 > 解决方案 > Python 3.6 邻接矩阵:如何以更好的方式获取它

问题描述

问题从一个经典的 csv 文件开始。一个例子可以是:

日期;出发地;命运;分钟;距离
19-02-2020;A;B;36;4
20-02-2020;A;B;33;4
24-02-2020;B;A;37;4
25- 02-2020;A;C;20;7
27-02-2020;C;B;20;3
28-02-2020;A;B;37.2;4
28-02-2020;A;Z;44;10

我的第一个想法是以经典的编程方式解决它:

循环 + 计数器变量并在矩阵中表示反计数器变量,如:ABCZ
A 0 3 1 1
B 1 0 0 0
C 0 1 0 0
Z 0 0 0 0

我的第一个问题是,是否有更好的自动方式在 python 中实现这一点,而不是 os 使用基于循环和计数器的经典编程算法。

以及如何获得更复杂的邻接矩阵,例如给您提供值的平均时间的邻接矩阵?

标签: python-3.xadjacency-matrix

解决方案


有类似的包networkx,但你可以使用 pandas 的 groupby。

我不认为带有 groupby 的 pandas 是最快的。我认为networkx会更快,但至少 groupby 比循环更好(我猜)。

import pandas as pd
import numpy as np

M = pd.read_csv('../sample_data.csv', sep=';')
M['constant'] = 1
print(M)
         date origing destiny  minutes  distance  constant
0  19-02-2020       A       B     36.0         4         1
1  20-02-2020       A       B     33.0         4         1
2  24-02-2020       B       A     37.0         4         1
3  25-02-2020       A       C     20.0         7         1
4  27-02-2020       C       B     20.0         3         1
5  28-02-2020       A       B     37.2         4         1
6  28-02-2020       A       Z     44.0        10         1

使用 groupby 我们可以得到计数;

counts = M.groupby(['origing','destiny']).count()[['constant']]
counts
                 constant
origing destiny          
A       B               3
        C               1
        Z               1
B       A               1
C       B               1

并将这些值存储在零矩阵中

def key_map(key):
    a,b = key
    return (ord(a) - ord('A'),ord(b)-ord('A'))

会得到 indicis,比如

counts['constant'].keys().map(key_map).values

我们将这些指标设置为任何值,我在这里进行计数,但您可以使用相同的 groupby 来聚合总和、平均值或其他列中的任何值;

indici =  np.array( [tuple(x) for x in counts['constant'].keys().map(key_map).values] )
indici = tuple(zip(*indici))

并存储

Z = np.zeros((26,26))
Z[ indici ] = counts['constant']

我只打印前几个

print(Z[:3,:3])
[[0. 3. 1.]
 [1. 0. 0.]
 [0. 1. 0.]]

推荐阅读