如何制作numpy棋盘?

Ned*_*der 21 python numpy

我正在使用numpy将像素阵列初始化为灰色棋盘("无像素"或透明的经典表示).看起来应该有一种奇怪的方式来做numpy的惊人的阵列分配/切片/切割操作,但这是我提出的最好的:

w, h = 600, 800
sq = 15    # width of each checker-square
self.pix = numpy.zeros((w, h, 3), dtype=numpy.uint8)
# Make a checkerboard
row = [[(0x99,0x99,0x99),(0xAA,0xAA,0xAA)][(i//sq)%2] for i in range(w)]
self.pix[[i for i in range(h) if (i//sq)%2 == 0]] = row
row = [[(0xAA,0xAA,0xAA),(0x99,0x99,0x99)][(i//sq)%2] for i in range(w)]
self.pix[[i for i in range(h) if (i//sq)%2 == 1]] = row
Run Code Online (Sandbox Code Playgroud)

它有效,但我希望更简单.

dou*_*oug 13

这应该做到这一点

你想要的任何尺寸棋盘(只需传递宽度和高度,如w,h); 我也将硬编码的单元格高度/宽度设置为1,但当然这也可以参数化,以便传递任意值:

>>> import numpy as NP

>>> def build_checkerboard(w, h) :
      re = NP.r_[ w*[0,1] ]              # even-numbered rows
      ro = NP.r_[ w*[1,0] ]              # odd-numbered rows
      return NP.row_stack(h*(re, ro))


>>> checkerboard = build_checkerboard(5, 5)

>>> checkerboard
 Out[3]: array([[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
               [1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
               [0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
               [1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
               [0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
               [1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
               [0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
               [1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
               [0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
               [1, 0, 1, 0, 1, 0, 1, 0, 1, 0]])
Run Code Online (Sandbox Code Playgroud)

使用这个2D数组,渲染棋盘图像很简单,如下所示:

>>> import matplotlib.pyplot as PLT

>>> fig, ax = PLT.subplots()
>>> ax.imshow(checkerboard, cmap=PLT.cm.gray, interpolation='nearest')
>>> PLT.show()
Run Code Online (Sandbox Code Playgroud)


Fal*_*lko 11

我会使用Kronecker产品 kron:

np.kron([[1, 0] * 4, [0, 1] * 4] * 4, np.ones((10, 10)))
Run Code Online (Sandbox Code Playgroud)

该示例中的棋盘具有2*4 = 8个字段,每个方向的大小为10x10.


unu*_*tbu 6

这是使用ogrid哪种方式更快的另一种方法:

import numpy as np
import Image

w, h = 600, 800
sq = 15
color1 = (0xFF, 0x80, 0x00)
color2 = (0x80, 0xFF, 0x00)

def use_ogrid():
    coords = np.ogrid[0:w, 0:h]
    idx = (coords[0] // sq + coords[1] // sq) % 2
    vals = np.array([color1, color2], dtype=np.uint8)
    img = vals[idx]
    return img

def use_fromfunction():
    img = np.zeros((w, h, 3), dtype=np.uint8)
    c = np.fromfunction(lambda x, y: ((x // sq) + (y // sq)) % 2, (w, h))
    img[c == 0] = color1
    img[c == 1] = color2
    return img

if __name__ == '__main__':
    for f in (use_ogrid, use_fromfunction):
        img = f()
        pilImage = Image.fromarray(img, 'RGB')
        pilImage.save('{0}.png'.format(f.func_name))
Run Code Online (Sandbox Code Playgroud)

以下是时间结果:

% python -mtimeit -s"import test" "test.use_fromfunction()"
10 loops, best of 3: 307 msec per loop
% python -mtimeit -s"import test" "test.use_ogrid()"
10 loops, best of 3: 129 msec per loop
Run Code Online (Sandbox Code Playgroud)


Ben*_*win 5

晚了,但为了后代:

def check(w, h, c0, c1, blocksize):
  tile = np.array([[c0,c1],[c1,c0]]).repeat(blocksize, axis=0).repeat(blocksize, axis=1)
  grid = np.tile(tile, ( h/(2*blocksize)+1, w/(2*blocksize)+1, 1))
  return grid[:h,:w]
Run Code Online (Sandbox Code Playgroud)


小智 5

您可以使用stepof start:stop:stepfor slicing方法来水平和垂直更新矩阵:这里x[1::2, ::2]从行上的第一个元素开始选择每隔一个元素,并为矩阵的每第二行选择。

import numpy as np
print("Checkerboard pattern:")
x = np.zeros((8,8),dtype=int)
# (odd_rows, even_columns)
x[1::2,::2] = 1
# (even_rows, odd_columns)
x[::2,1::2] = 1
print(x)
Run Code Online (Sandbox Code Playgroud)


Eel*_*orn 5

def checkerboard(shape):
    return np.indices(shape).sum(axis=0) % 2
Run Code Online (Sandbox Code Playgroud)

最紧凑,可能最快,也是唯一发布到n维的解决方案。

  • 有人可以解释这个解决方案吗? (3认同)
  • 非常巧妙的实现! (2认同)
  • @HazimAhmed `np.indices(shape)` 创建两个不同的数组,一个在每行中具有升序整数,一个在每列中具有升序整数。一旦对它们求和,您就会得到一个行和列中都有升序整数的单个矩阵(例如,第一行来自 [0,...,9],第二行来自 [1,...,10] 等。 )。一旦你进行模运算,你就会得到行和列中交替的余数——这正是一个棋盘。确实是巧妙的实施。 (2认同)

小智 5

您可以使用 Numpy 的tile函数来获取大小的棋盘格数组,n*m其中 n 和 m 应该是偶数以获得正确的结果......

def CreateCheckboard(n,m):
    list_0_1 = np.array([ [ 0, 1], [ 1, 0] ])
    checkerboard = np.tile(list_0_1, ( n//2, m//2)) 
    print(checkerboard.shape)
    return checkerboard
CreateCheckboard(4,6)
Run Code Online (Sandbox Code Playgroud)

这给出了输出:

(4, 6)
array([[0, 1, 0, 1, 0, 1],
       [1, 0, 1, 0, 1, 0],
       [0, 1, 0, 1, 0, 1],
       [1, 0, 1, 0, 1, 0]])

Run Code Online (Sandbox Code Playgroud)


tel*_*t99 3

不能使用hstack和vstack吗?看这里。像这样:

>>> import numpy as np
>>> b = np.array([0]*4)
>>> b.shape = (2,2)
>>> w = b + 0xAA
>>> r1 = np.hstack((b,w,b,w,b,w,b))
>>> r2 = np.hstack((w,b,w,b,w,b,w))
>>> board = np.vstack((r1,r2,r1,r2,r1,r2,r1))
Run Code Online (Sandbox Code Playgroud)