【问题标题】:2d array diamond shape of 1's of size x [duplicate]尺寸为x的1的二维阵列菱形[重复]
【发布时间】:2025-12-05 17:55:02
【问题描述】:

嘿,我正在尝试制作一个由 1 和 0 组成的二维数组,其中 1 形成菱形。钻石的大小应为 x:

尺寸 x = 3 的菱形看起来像这样:

[[0 0 1 0 0]
 [0 1 0 1 0]
 [1 0 0 0 1]
 [0 1 0 1 0]
 [0 0 1 0 0]]

尺寸 x = 1 的钻石形状如下所示:

[[1]]

有人知道如何实现吗?我认为numpy.eyeconcatenate 可能有用。但是,我找不到解决方案

【问题讨论】:

标签: python python-3.x numpy


【解决方案1】:

我将利用numpy.diagflatnumpy.flip 结合以下方式:

import numpy as np
arr = np.diagflat([1,1,1],2)  # now we have 1s in upper-right part
arr = np.maximum(arr,np.flip(arr,1))  # now we have 1s in upper part
arr = np.maximum(arr,np.flip(arr,0))  # now we have 1s everywhere
print(arr)

输出:

[[0 0 1 0 0]
 [0 1 0 1 0]
 [1 0 0 0 1]
 [0 1 0 1 0]
 [0 0 1 0 0]]

【讨论】:

  • 这比我的解决方案快!
  • 哈!有一个np.pad( . . . , mode = 'reflect') 的单线可能更快,让我看看
  • 好吧,我不明白np.pad 怎么能用于一个班轮? This 我猜答案可能被称为一个班轮!
  • @anurag diamond = lambda n: np.pad(np.eye(n), ((n-1, 0), (0, n-1)), mode = 'reflect') 我的甚至适合评论:P
【解决方案2】:

这里是np.eye的解决方案

import numpy as np

def diamond(n):
    a, b = np.eye(n, dtype=int), np.eye(n, dtype=int)[:,::-1]

    c, d = np.hstack((b,a[:,1:])), np.hstack((a,b[:,1:]))

    return np.vstack((c, d[1:,:]))

输出:

>>> print(diamond(3))

[[0 0 1 0 0]
 [0 1 0 1 0]
 [1 0 0 0 1]
 [0 1 0 1 0]
 [0 0 1 0 0]]

【讨论】:

    【解决方案3】:

    我的条目使用np.pad(... mode = 'reflect')

    def diamond(n):
        return np.pad(np.eye(n), ((n-1, 0), (0, n-1)), mode = 'reflect')
        
    
    diamond(3)
    Out: 
    array([[0., 0., 1., 0., 0.],
           [0., 1., 0., 1., 0.],
           [1., 0., 0., 0., 1.],
           [0., 1., 0., 1., 0.],
           [0., 0., 1., 0., 0.]])
    
    diamond(1)
    Out: array([[1.]])
    
    diamond(5)
    Out: 
    array([[0., 0., 0., 0., 1., 0., 0., 0., 0.],
           [0., 0., 0., 1., 0., 1., 0., 0., 0.],
           [0., 0., 1., 0., 0., 0., 1., 0., 0.],
           [0., 1., 0., 0., 0., 0., 0., 1., 0.],
           [1., 0., 0., 0., 0., 0., 0., 0., 1.],
           [0., 1., 0., 0., 0., 0., 0., 1., 0.],
           [0., 0., 1., 0., 0., 0., 1., 0., 0.],
           [0., 0., 0., 1., 0., 1., 0., 0., 0.],
           [0., 0., 0., 0., 1., 0., 0., 0., 0.]])
    

    在我的时间里,这比@Daweo 的答案快 40%,而且代码也更简单

    def diamond_Daweo(n):
        arr = np.diagflat(np.ones(n), n-1)  # now we have 1s in upper-right part
        arr = np.maximum(arr,np.flip(arr,1))  # now we have 1s in upper part
        return np.maximum(arr,np.flip(arr,0))  # now we have 1s everywhere
    
    %timeit diamond_Daweo(100)
    120 µs ± 1.9 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
    
    %timeit diamond(100)
    75.8 µs ± 2.86 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
    

    【讨论】:

      【解决方案4】:

      以下解决方案使用numpy.eyenumpy.flip 来定义正确大小的数组,其中填充了代表绘制菱形所需线条的数组(一个对角线左上(lu)和一个对角线左下( ld)。

      numpy.zeros 然后用于创建一个正确尺寸的数组,以存储每条边上都有size 的钻石(d)。每个维度都是size*2-1,以允许沿每个轴的两条线的全宽,-1 占顶点/角。

      然后,numpy.where 用于有效地将上面生成的两种类型的线映射到更正 d 上的位置以“绘制”菱形。这是通过首先对d 进行切片来实现的,以便在使用lu/ld 生成应用于相关选择以填充这些选择之前,每行都从正确的索引开始。

      import numpy as np
      
      def diamond(size):
          lu = np.eye(size) # Define left-upward edge
          ld = np.flip(lu, axis=0) # Define left-downward edge
          d = np.zeros((lu.shape[0]*2-1, lu.shape[1]*2-1)) # Create empty array of correct size filled with zeros
          mid = size-1 # Store mid-point index of each axis
          d[np.where(ld==1)] = 1 # Write upper left-centre edge
          d[:,mid:][np.where(lu==1)] = 1 # Write upper centre-right edge
          d[mid:,mid:][np.where(ld==1)] = 1 # Write lower right-centre edge
          d[mid:,:][np.where(lu==1)] = 1 # Write lower left-centre edge
          return d.astype(int) # Return diamond shaped array with values int instead of float
      
      print(diamond(1),'\n')
      print(diamond(2),'\n')
      print(diamond(3),'\n')
      print(diamond(4),'\n')
      

      输出

      [[1]]
      
      [[0 0 1 0 0]
       [0 1 0 1 0]
       [1 0 0 0 1]
       [0 1 0 1 0]
       [0 0 1 0 0]]
      
      [[0 0 1 0 0]
       [0 1 0 1 0]
       [1 0 0 0 1]
       [0 1 0 1 0]
       [0 0 1 0 0]]
      
      [[0 0 0 1 0 0 0]
       [0 0 1 0 1 0 0]
       [0 1 0 0 0 1 0]
       [1 0 0 0 0 0 1]
       [0 1 0 0 0 1 0]
       [0 0 1 0 1 0 0]
       [0 0 0 1 0 0 0]]
      
      

      【讨论】:

        【解决方案5】:

        如果你想使用 numpy.eye,这行得通。虽然有点复杂。

        dim = 8
        A = np.maximum(np.maximum(np.maximum(np.eye(dim, k=-(dim//2)), np.eye(dim, k=(dim//2))), np.fliplr(np.eye(dim, k=(dim//2)))), np.fliplr(np.eye(dim, k=-(dim//2))))
        

        【讨论】:

          【解决方案6】:

          生成任何所需大小的菱形矩阵的通用代码。 使用单位矩阵和切片技术。

          import numpy as np
          
          x = 5  # assuming, this will always be odd
          
          result_sz = 2*x-1
          mid_pt = int(np.floor(result_sz/2.0))
          
          result = np.zeros((result_sz, result_sz), dtype=np.int)
          tile = np.eye(x)
          
          # we have four regular graph quadrants
          # first quadrant
          result[0:x, mid_pt:] = tile    # direct identity
          # second quadrant
          result[mid_pt:, mid_pt:] = np.flip(tile, axis=1)     # identity flipped about y-axis
          # third quadrant
          result[mid_pt:, 0:x] = tile   # direct identity
          # fourth quadrant
          result[0:x, 0:x] = np.flip(tile, axis=0)     # identity flipped about x-axis
          
          # The diamond matrix
          print(result)
          

          【讨论】:

            【解决方案7】:
            def diamond(m):
                n = 2 * m - 1
                res = [[0] * n for _ in range(n)]
                # make first m lines
                for x in range(m):
                    res[x][m - x - 1] = 1
                    res[x][n - (m - x)] = 1
                # copy other lines as they as symmetric with above line by line m - 1
                for x in range(m, n):
                    res[x] = res[2 * (m - 1) - x][:]
                return res
            

            【讨论】:

              最近更新 更多