Вот метод, использующий scipy.spatial.distance.squareform
:
squareform
переключается между полной и «сжатой» формами симметричной матрицы:
>>> full = squareform(np.arange(1,11))
>>> full
array([[ 0, 1, 2, 3, 4],
[ 1, 0, 5, 6, 7],
[ 2, 5, 0, 8, 9],
[ 3, 6, 8, 0, 10],
[ 4, 7, 9, 10, 0]])
>>> squareform(full)
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
Так как он был разработан с учетом матрицы расстояний, он оставляет диагональ на нуле, поэтому мы должны заполнить ее вручную. Для этого мы используем einsum
, который использовался так, как мы возвращаем записываемое представление диагонали,
>>> from scipy.spatial.distance import squareform
>>>
>>> N = 5
>>> a = squareform(np.random.random(N*(N-1)//2))
>>> np.einsum('ii->i', a)[:] = np.random.random(N)
>>> a
array([[0.29946651, 0.3636706 , 0.00708741, 0.87536594, 0.62197293],
[0.3636706 , 0.31774527, 0.05597852, 0.10800514, 0.99871399],
[0.00708741, 0.05597852, 0.83912235, 0.86241008, 0.01806965],
[0.87536594, 0.10800514, 0.86241008, 0.11039534, 0.64213608],
[0.62197293, 0.99871399, 0.01806965, 0.64213608, 0.84755054]])