Python:Numpy切片深入分解[关闭]

发布于 2021-01-29 15:12:11

已关闭 。这个问题需要更加集中。它当前不接受答案。


想改善这个问题吗? 更新问题,使其仅通过编辑此帖子来关注一个问题。

2年前关闭。

改善这个问题

我在conway的生活游戏克隆中找到了以下代码。我不明白下面的代码是如何运行的。有人可以深入解释代码的执行方式吗?

def iterate(Z):
    # find number of neighbors that each square has
    N = np.zeros(Z.shape)
    N[1:, 1:] += Z[:-1, :-1]
    N[1:, :-1] += Z[:-1, 1:]
    N[:-1, 1:] += Z[1:, :-1]
    N[:-1, :-1] += Z[1:, 1:]
    N[:-1, :] += Z[1:, :]
    N[1:, :] += Z[:-1, :]
    N[:, :-1] += Z[:, 1:]
    N[:, 1:] += Z[:, :-1]
    # a live cell is killed if it has fewer than 2 or more than 3 neighbours.
    part1 = ((Z == 1) & (N < 4) & (N > 1))
    # a new cell forms if a square has exactly three members
    part2 = ((Z == 0) & (N == 3))
    return (part1 | part2).astype(int)
关注者
0
被浏览
138
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    print(N)在所有行之后添加一行N+=,然后尝试各种Z数组。

    例如

    定义一个小的z,中间有一个1s的块:

    In [29]: z = np.zeros((10,10),int)
    In [31]: z[4:6,4:6]=1
    In [34]: z[4:8,5]=1
    
    In [35]: z
    Out[35]: 
    array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
           [0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
    

    传递给函数:

    In [36]: iterate(z)
    [[ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]
     [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]
     [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]
     [ 0.  0.  0.  1.  2.  2.  1.  0.  0.  0.]
     [ 0.  0.  0.  2.  3.  3.  2.  0.  0.  0.]
     [ 0.  0.  0.  2.  4.  4.  3.  0.  0.  0.]
     [ 0.  0.  0.  1.  4.  3.  3.  0.  0.  0.]
     [ 0.  0.  0.  0.  2.  1.  2.  0.  0.  0.]
     [ 0.  0.  0.  0.  1.  1.  1.  0.  0.  0.]
     [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]]
    

    N 已经计算出邻居的数量为1。自己检查一下计数。

    Out[36]: 
    array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
           [0, 0, 0, 0, 0, 1, 1, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
    

    尝试各种图案,重复进行迭代,然后观察图案变化。有些人死了,有些人以命令的方式移动,有些“眨眼”等。

    在像这样的行中:

    N[1:, 1:] += Z[:-1, :-1]
    

    RHS是左上方(此处为9x9);LHS是右下角,同样是9x9。有8个N+=表达式,计算8个邻居(在3x3块中减去中心)。使用此偏移量切片,它可以Z一次对所有点进行计数。

    首先,1行数组可能更容易可视化

    In [47]: z = np.zeros((1,10),int)
    In [49]: z[0,4:7]=1
    In [50]: z
    Out[50]: array([[0, 0, 0, 0, 1, 1, 1, 0, 0, 0]])
    In [51]: iterate(z)
    [[ 0.  0.  0.  1.  1.  2.  1.  1.  0.  0.]]
    Out[51]: array([[0, 0, 0, 0, 0, 1, 0, 0, 0, 0]])
    

    我认为,如果所有边缘值z均为0,效果最好。

    此数组创建gliderhttps://en.wikipedia.org/wiki/Glider_(Conway%27s_Life)上进行动画处理的

    In [64]: z = np.zeros((10,10),int)
    In [65]: z[1,2]=1;z[2,3]=1;z[3,1:4]=1
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看