2048 게임 데모에서 매트릭스의 콘텐츠를 이동하기 위한 코드 최적화를 모색하고 있습니다. 특히, 행렬의 0이 아닌 값을 왼쪽, 오른쪽, 위 또는 아래로 이동하려면 함수가 필요합니다.
제공된 코드는 다음에서 영감을 받은 벡터화된 접근 방식을 제공합니다. 다른 게시물:
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
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]])
일반 n차원 배열의 경우 코드를 다음과 같이 수정할 수 있습니다.
def justify_nd(a, invalid_val, axis, side): """ Justify ndarray for the valid elements (that are not invalid_val). Parameters ---------- A : ndarray Input array to be justified invalid_val : scalar invalid value axis : int Axis along which justification is to be made side : str Direction of justification. Must be 'front' or 'end'. So, with 'front', valid elements are pushed to the front and with 'end' valid elements are pushed to the end along specified axis. """ pushax = lambda a: np.moveaxis(a, axis, -1) if invalid_val is np.nan: mask = ~np.isnan(a) else: mask = a!=invalid_val justified_mask = np.sort(mask,axis=axis) if side=='front': justified_mask = np.flip(justified_mask,axis=axis) out = np.full(a.shape, invalid_val) if (axis==-1) or (axis==a.ndim-1): out[justified_mask] = a[mask] else: pushax(out)[pushax(justified_mask)] = pushax(a)[pushax(mask)] return out
In [87]: a Out[87]: array([[[54, 57, 0, 77], [77, 0, 0, 31], [46, 0, 0, 98], [98, 22, 68, 75]], [[49, 0, 0, 98], [ 0, 47, 0, 87], [82, 19, 0, 90], [79, 89, 57, 74]], [[ 0, 0, 0, 0], [29, 0, 0, 49], [42, 75, 0, 67], [42, 41, 84, 33]], [[ 0, 0, 0, 38], [44, 10, 0, 0], [63, 0, 0, 0], [89, 14, 0, 0]]])
'앞'으로, 축을 따라 =0 :
In [88]: justify_nd(a, invalid_val=0, axis=0, side='front') Out[88]: array([[[54, 57, 0, 77], [77, 47, 0, 31], [46, 19, 0, 98], [98, 22, 68, 75]], [[49, 0, 0, 98], [29, 10, 0, 87], [82, 75, 0, 90], [79, 89, 57, 74]], [[ 0, 0, 0, 38], [44, 0, 0, 49], [42, 0, 0, 67], [42, 41, 84, 33]], [[ 0, 0, 0, 0], [ 0, 0, 0, 0], [63, 0, 0, 0], [89, 14, 0, 0]]])
축을 따라=1 :
In [89]: justify_nd(a, invalid_val=0, axis=1, side='front') Out[89]: array([[[54, 57, 68, 77], [77, 22, 0, 31], [46, 0, 0, 98], [98, 0, 0, 75]], [[49, 47, 57, 98], [82, 19, 0, 87], [79, 89, 0, 90], [ 0, 0, 0, 74]], [[29, 75, 84, 49], [42, 41, 0, 67], [42, 0, 0, 33], [ 0, 0, 0, 0]], [[44, 10, 0, 38], [63, 14, 0, 0], [89, 0, 0, 0], [ 0, 0, 0, 0]]])
축을 따라=2 :
위 내용은 NumPy 배열을 어떻게 효율적으로 정렬(이동)할 수 있나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!