Python: 调整NumPy数组

我刚开始学习Python,感觉还不错,我甚至可以说Python非常性感,直到我需要移动一个4×4矩阵的内容,我打算用它来构建一个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]]

请问有人能帮我用numpy的方式实现这个功能吗?我相信这样会更快,代码也会更少(我是在深度优先搜索算法中使用),更重要的是,实现cover_upcover_downcover_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'):        """    调整二维数组    参数    ----------    A : ndarray        输入数组,需要调整    axis : int        调整的轴    side : str        调整的方向。可以是'left', 'right', 'up', 'down'        对于axis=1,应该是'left'或'right',对于axis=0,应该是'up'或'down'。    """    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 # 输入数组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,我们可以修改为 –

def justify_nd(a, invalid_val, axis, side):        """    调整ndarray中有效元素(非invalid_val)。    参数    ----------    A : ndarray        输入数组,需要调整    invalid_val : scalar        无效值    axis : int        调整的轴    side : str        调整的方向。必须是'front'或'end'。        因此,使用'front'时,有效元素被推到前面,        使用'end'时,有效元素被推到指定轴的末尾。    """        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]: aOut[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]]])

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注