Python:证明NumPy数组的合理性

Python:证明NumPy数组的合理性,python,numpy,search,artificial-intelligence,2048,Python,Numpy,Search,Artificial Intelligence,2048,请告诉我,我对Python有点陌生,它一直都很不错,我可以说Python非常性感,直到我需要转换4x4矩阵的内容,我想用它来构建2048游戏的演示,我有这个功能 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):

请告诉我,我对
Python有点陌生,它一直都很不错,我可以说Python非常性感,直到我需要转换4x4矩阵的内容,我想用它来构建2048游戏的演示,我有这个功能

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
如果你这样调用这个函数,它就是这样做的

cover_left([
              [1,0,2,0], 
              [3,0,4,0], 
              [5,0,6,0], 
              [0,7,0,8]
          ])
它将覆盖左侧的零并生成

[  [1, 2, 0, 0],
   [3, 4, 0, 0],
   [5, 6, 0, 0],
   [7, 8, 0, 0]]
请我需要有人来帮助我,我相信这样做会更快,需要更少的代码(我使用的是深度优先搜索算法),更重要的是实现
cover\u up
cover\u down
cover\u 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]]

这是一种矢量化方法,其灵感来源于并推广到涵盖所有四个方向的
非零
-

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]])
一般情况(ndarray) 例如,我们可以将其修改为-

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 [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]])
输入阵列:

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

In [90]: justify_nd(a, invalid_val=0, axis=2, side='front')
Out[90]: 
array([[[54, 57, 77,  0],
        [77, 31,  0,  0],
        [46, 98,  0,  0],
        [98, 22, 68, 75]],

       [[49, 98,  0,  0],
        [47, 87,  0,  0],
        [82, 19, 90,  0],
        [79, 89, 57, 74]],

       [[ 0,  0,  0,  0],
        [29, 49,  0,  0],
        [42, 75, 67,  0],
        [42, 41, 84, 33]],

       [[38,  0,  0,  0],
        [44, 10,  0,  0],
        [63,  0,  0,  0],
        [89, 14,  0,  0]]])
“结束”

In [94]: justify_nd(a, invalid_val=0, axis=2, side='end')
Out[94]: 
array([[[ 0, 54, 57, 77],
        [ 0,  0, 77, 31],
        [ 0,  0, 46, 98],
        [98, 22, 68, 75]],

       [[ 0,  0, 49, 98],
        [ 0,  0, 47, 87],
        [ 0, 82, 19, 90],
        [79, 89, 57, 74]],

       [[ 0,  0,  0,  0],
        [ 0,  0, 29, 49],
        [ 0, 42, 75, 67],
        [42, 41, 84, 33]],

       [[ 0,  0,  0, 38],
        [ 0,  0, 44, 10],
        [ 0,  0,  0, 63],
        [ 0,  0, 89, 14]]])

多亏了这一切,这才是我以后使用的

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

这与基本相同,只是有四个条件语句。这里有什么新消息?签名不同,而且他修改了他的答案。。。在什么签名之前不是这样的?一个输入参数有四个输入选项,所以有四个条件语句。另一篇文章有两个输入选项,用于两个输入参数。基本上是一样的。在你发布这篇文章之前,另一篇文章经过了12分钟的修改。是否可以不调用np.sort来完成这项操作,这会降低发布速度runtime@qwertylpc输入数组的实际形状是什么?该数组在2-7(99.99%的时间)之间动态更改行,但有100000列。我只需要你写的up-justify函数。这个提交的票证能适应字符串值数组吗?实际字母表,而不是存储为字符串的数字。