Por lo tanto, mi objective es el siguiente, dado el tamaño de la matriz s
, estoy intentando crear una matriz similar a la siguiente, pero para el tamaño sxs
:
[1 1 0] [1 1 1] [0 1 1]
Para el tamaño de 4×4, se vería algo como lo siguiente:
[1 1 0 0] [1 1 1 0] [0 1 1 1] [0 0 1 1]
Por lo tanto, puede observar un patrón: hay s-1
número s-1
de matrices superpuestas mini 2x2
superpuestas.
Estaba pensando en crear una matriz de 2x2
y luego usar una referencia dinámica (¿para un bucle?) Como B[:-1,:-1] = ones_matrix
, donde B
es la matriz de ceros de tamaño sxs
. Pero no estoy seguro de cómo incorporar un bucle for aquí, porque si tomamos, por ejemplo, una matriz 4x4
, tendríamos que hacer referencia a B
de tres maneras: B[:-1,:-1] = ones_matrix, B[1:-1,1:-1] = ones_matrix, B[2:,2:]=ones_matrix
. Y no puedo encontrar una manera de hacerlo dinámicamente para una matriz de ceros de tamaño n
. ¿Hay tal vez otra forma de hacer esto?
Método # 1: en lugar de un grupo de matrices 2×2, podría ser más fácil verlo como tres diagonales de 1 y combinarlas:
>>> s = 3 >>> np.diag([1]*s,0) + np.diag([1]*(s-1),-1) + np.diag([1]*(s-1), 1) array([[1, 1, 0], [1, 1, 1], [0, 1, 1]]) >>> s = 4 >>> np.diag([1]*s,0) + np.diag([1]*(s-1),-1) + np.diag([1]*(s-1), 1) array([[1, 1, 0, 0], [1, 1, 1, 0], [0, 1, 1, 1], [0, 0, 1, 1]])
Método # 2: (inspirado en la respuesta de Divankar), podemos pensar en términos de distancia desde el centro:
>>> s = 4 >>> i,j = np.indices((s,s)) >>> (abs(ij) <= 1).astype(int) array([[1, 1, 0, 0], [1, 1, 1, 0], [0, 1, 1, 1], [0, 0, 1, 1]])
Método # 3: podríamos aprovechar tril
o triu
y hacer algo de aritmética:
>>> m = np.tril(np.ones((s,s)),1) >>> m * mT array([[ 1., 1., 0., 0., 0.], [ 1., 1., 1., 0., 0.], [ 0., 1., 1., 1., 0.], [ 0., 0., 1., 1., 1.], [ 0., 0., 0., 1., 1.]]) >>> m = np.tril(np.ones((s,s)),2) >>> m * mT array([[ 1., 1., 1., 0., 0.], [ 1., 1., 1., 1., 0.], [ 1., 1., 1., 1., 1.], [ 0., 1., 1., 1., 1.], [ 0., 0., 1., 1., 1.]])
Enfoque vectorizado con broadcasting
.
A = np.arange(s) out = ((A[:,None] < A+2) & (A[:,None] > A-2)).astype(int)
Ejecución de la muestra
In [60]: s = 3 ...: A = np.arange(s) ...: out = ((A[:,None] < A+2) & (A[:,None] > A-2)).astype(int) ...: In [61]: out Out[61]: array([[1, 1, 0], [1, 1, 1], [0, 1, 1]]) In [62]: s = 4 ...: A = np.arange(s) ...: out = ((A[:,None] < A+2) & (A[:,None] > A-2)).astype(int) ...: In [63]: out Out[63]: array([[1, 1, 0, 0], [1, 1, 1, 0], [0, 1, 1, 1], [0, 0, 1, 1]])
Podrías usar sympy.Matrix también:
from sympy import Matrix Matrix(4, 4, lambda i,j: 1 if (-2