从一维数组获取二维数组(一种邻接矩阵)的有效方法

Efficient way to get 2d array (kind of adjacency matrix) from 1d array

对于数组,例如 a = np.array([1,2,1,0,0,1,1,2,2,2]),需要创建邻接“矩阵”A 之类的东西。 IE。 A 是一个对称的 (n, n) numpy 数组,其中 n = len(a)A[i,j] = 1 如果 a[i] == a[j]0 否则(i = 0...n-1j = 0...n-1):

  0 1 2 3 4 5 6 7 8 9
0 1 0 1 0 0 1 1 0 0 0
1   1 0 0 0 0 0 1 1 1
2     1 0 0 1 1 0 0 0
3       1 1 0 0 0 0 0
4         1 0 0 0 0 0
5           1 1 0 0 0
6             1 0 0 0
7               1 1 1
8                 1 1
9                   1

简单的解决方案是

n = len(a)
A = np.zeros([n, n]).astype(int)
for i in range(n):
    for j in range(n):
        if a[i] == a[j]:
            A[i, j] = 1
        else:
            A[i, j] = 0

能否以 numpy 方式完成,即没有循环?

您可以使用 numpy broadcasting:

b = (a[:,None]==a).astype(int)
df = pd.DataFrame(b)

输出:

   0  1  2  3  4  5  6  7  8  9
0  1  0  1  0  0  1  1  0  0  0
1  0  1  0  0  0  0  0  1  1  1
2  1  0  1  0  0  1  1  0  0  0
3  0  0  0  1  1  0  0  0  0  0
4  0  0  0  1  1  0  0  0  0  0
5  1  0  1  0  0  1  1  0  0  0
6  1  0  1  0  0  1  1  0  0  0
7  0  1  0  0  0  0  0  1  1  1
8  0  1  0  0  0  0  0  1  1  1
9  0  1  0  0  0  0  0  1  1  1

如果只需要上三角,使用numpy.tril_indices:

b = (a[:,None]==a).astype(float)
b[np.tril_indices_from(b, k=-1)] = np.nan
df = pd.DataFrame(b)

输出:

     0    1    2    3    4    5    6    7    8    9
0  1.0  0.0  1.0  0.0  0.0  1.0  1.0  0.0  0.0  0.0
1  NaN  1.0  0.0  0.0  0.0  0.0  0.0  1.0  1.0  1.0
2  NaN  NaN  1.0  0.0  0.0  1.0  1.0  0.0  0.0  0.0
3  NaN  NaN  NaN  1.0  1.0  0.0  0.0  0.0  0.0  0.0
4  NaN  NaN  NaN  NaN  1.0  0.0  0.0  0.0  0.0  0.0
5  NaN  NaN  NaN  NaN  NaN  1.0  1.0  0.0  0.0  0.0
6  NaN  NaN  NaN  NaN  NaN  NaN  1.0  0.0  0.0  0.0
7  NaN  NaN  NaN  NaN  NaN  NaN  NaN  1.0  1.0  1.0
8  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  1.0  1.0
9  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  1.0