Python: Justificación de la matriz NumPy
search artificial-intelligence (2)
Aquí hay un enfoque vectorizado inspirado en
this other post
y generalizado para cubrir
non-zeros
en las cuatro direcciones:
def justify(a, invalid_val=0, axis=1, side=''left''):
"""
Justifies a 2D array
Parameters
----------
A : ndarray
Input array to be justified
axis : int
Axis along which justification is to be made
side : str
Direction of justification. It could be ''left'', ''right'', ''up'', ''down''
It should be ''left'' or ''right'' for axis=1 and ''up'' or ''down'' for axis=0.
"""
if invalid_val is np.nan:
mask = ~np.isnan(a)
else:
mask = a!=invalid_val
justified_mask = np.sort(mask,axis=axis)
if (side==''up'') | (side==''left''):
justified_mask = np.flip(justified_mask,axis=axis)
out = np.full(a.shape, invalid_val)
if axis==1:
out[justified_mask] = a[mask]
else:
out.T[justified_mask.T] = a.T[mask.T]
return out
Ejecuciones de muestra:
In [473]: a # input array
Out[473]:
array([[1, 0, 2, 0],
[3, 0, 4, 0],
[5, 0, 6, 0],
[6, 7, 0, 8]])
In [474]: justify(a, axis=0, side=''up'')
Out[474]:
array([[1, 7, 2, 8],
[3, 0, 4, 0],
[5, 0, 6, 0],
[6, 0, 0, 0]])
In [475]: justify(a, axis=0, side=''down'')
Out[475]:
array([[1, 0, 0, 0],
[3, 0, 2, 0],
[5, 0, 4, 0],
[6, 7, 6, 8]])
In [476]: justify(a, axis=1, side=''left'')
Out[476]:
array([[1, 2, 0, 0],
[3, 4, 0, 0],
[5, 6, 0, 0],
[6, 7, 8, 0]])
In [477]: justify(a, axis=1, side=''right'')
Out[477]:
array([[0, 0, 1, 2],
[0, 0, 3, 4],
[0, 0, 5, 6],
[0, 6, 7, 8]])
Por favor, soy un poco nuevo en
Python
y ha sido agradable, podría comentar que Python es muy sexy hasta que necesité cambiar el contenido de una matriz 4x4 que quiero usar para construir una demostración del juego 2048.
here
estoy. esta función
def cover_left(matrix):
new=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
for i in range(4):
count=0
for j in range(4):
if mat[i][j]!=0:
new[i][count]=mat[i][j]
count+=1
return new
Esto es lo que hace esta función si la llamas así
cover_left([
[1,0,2,0],
[3,0,4,0],
[5,0,6,0],
[0,7,0,8]
])
Cubrirá los ceros a la izquierda y producirá
[ [1, 2, 0, 0],
[3, 4, 0, 0],
[5, 6, 0, 0],
[7, 8, 0, 0]]
Por favor, necesito que alguien me ayude con una forma
numpy
de hacer esto, que creo que será más rápido y requerirá menos código (lo estoy usando en un
cover_up
de búsqueda de profundidad primero) y, lo que es más importante, la implementación de
cover_up
,
cover_down
y
`cover_left`.
`cover_up`
[ [1, 7, 2, 8],
[3, 0, 4, 0],
[5, 0, 6, 0],
[0, 0, 0, 0]]
`cover_down`
[ [0, 0, 0, 0],
[1, 0, 2, 0],
[3, 0, 4, 0],
[5, 7, 6, 8]]
`cover_right`
[ [0, 0, 1, 2],
[0, 0, 3, 4],
[0, 0, 5, 6],
[0, 0, 7, 8]]
Gracias por adelantado.
Gracias a todo esto es lo que luego uso
def justify(a, direction):
mask = a>0
justified_mask = numpy.sort(mask,0) if direction == ''up'' or direction ==''down'' else numpy.sort(mask, 1)
if direction == ''up'':
justified_mask = justified_mask[::-1]
if direction ==''left'':
justified_mask = justified_mask[:,::-1]
if direction ==''right'':
justified_mask = justified_mask[::-1, :]
out = numpy.zeros_like(a)
out.T[justified_mask.T] = a.T[mask.T]
return out