То, что вы просите здесь, известно как матрица Теплица , которая:
матрица, в которой каждая нисходящая диагональ слева направо является постоянной
К счастью для вас, scipy
имеет простую в использовании реализацию этого:
from scipy.linalg import toeplitz
def magic_toeplitz(arr, to_add):
return toeplitz(np.hstack([to_add, arr[::-1]]), np.hstack([to_add, arr]))
a = [6,7,8,9]
add = [1]
magic_toeplitz(a, add)
array([[1, 6, 7, 8, 9],
[9, 1, 6, 7, 8],
[8, 9, 1, 6, 7],
[7, 8, 9, 1, 6],
[6, 7, 8, 9, 1]])
Векторизованный способ масштабирования этого решения:
A = np.array([1, 2, 3, 4, 5])
B = np.array([6, 7, 8, 9])
out = toeplitz(np.hstack([[np.nan], B[::-1]]), np.hstack([np.nan, B]))
out = np.tile(out, (len(A), 1, 1))
m = np.ma.array(out, mask=np.isnan(out))
vals = np.repeat(A, (B.shape[0] + 1)**2).reshape(out.shape)
print(m.filled(vals))
array([[[1, 6, 7, 8, 9],
[9, 1, 6, 7, 8],
[8, 9, 1, 6, 7],
[7, 8, 9, 1, 6],
[6, 7, 8, 9, 1]],
[[2, 6, 7, 8, 9],
[9, 2, 6, 7, 8],
[8, 9, 2, 6, 7],
[7, 8, 9, 2, 6],
[6, 7, 8, 9, 2]],
[[3, 6, 7, 8, 9],
[9, 3, 6, 7, 8],
[8, 9, 3, 6, 7],
[7, 8, 9, 3, 6],
[6, 7, 8, 9, 3]],
[[4, 6, 7, 8, 9],
[9, 4, 6, 7, 8],
[8, 9, 4, 6, 7],
[7, 8, 9, 4, 6],
[6, 7, 8, 9, 4]],
[[5, 6, 7, 8, 9],
[9, 5, 6, 7, 8],
[8, 9, 5, 6, 7],
[7, 8, 9, 5, 6],
[6, 7, 8, 9, 5]]])