Python:证明 NumPy 数组 [英] Python: Justifying NumPy array

查看:23
本文介绍了Python:证明 NumPy 数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

拜托,我对 Python 有点陌生,这很好,我可以评论说 python 非常性感,直到我需要移动我想用于构建一个 4x4 矩阵的内容游戏的2048游戏演示是这里我有这个功能

Please I am a bit new to Python and it has been nice, I could comment that python is very sexy till I needed to shift content of a 4x4 matrix which I want to use in building a 2048 game demo of the game is here I have this function

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

如果你这样调用它,这就是这个函数的作用

This is what this function does if you call it like this

cover_left([
              [1,0,2,0], 
              [3,0,4,0], 
              [5,0,6,0], 
              [0,7,0,8]
          ])

它将覆盖左边的零并产生

It will cover the zeros to the left and produce

[  [1, 2, 0, 0],
   [3, 4, 0, 0],
   [5, 6, 0, 0],
   [7, 8, 0, 0]]

请我需要有人用 numpy 的方式来帮助我这样做,我相信它会更快并且需要更少的代码(我在深度优先搜索算法中使用),更重要的是cover_upcover_downcover_left 的实现.

Please I need someone to help me with a numpy way of doing this which I believe will be faster and require less code (I am using in a depth-first search algo) and more importantly the implementation of cover_up, cover_down and 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]]

推荐答案

这是一种矢量化方法,灵感来自 另一个帖子 并推广到所有四个方向的非零 -

Here's a vectorized approach inspired by this other post and generalized to cover non-zeros for all four directions -

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)

对于 ndarray,我们可以将其修改为 -

Generic case (ndarray)

For a ndarray, we could modify it to -

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]]])

'front',沿axis =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]]])

沿 axis=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]]])

沿 axis=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]]])

'end':

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]]])

这篇关于Python:证明 NumPy 数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆