Skip to main content
 首页 » 编程设计

python之高效创建 0 和 255 的棋盘图案

2025年05月04日14sharpest

我写了一个函数来通过 for 循环生成一个示例 numpy 数组。但是对于更大的维度来说太慢了。

import numpy as np 
mat = np.zeros((5, 5)) 
 
def func(im): 
    im = im.copy() 
    h,w = im.shape 
    for i in range(h): 
        for j in range(w): 
            if (i + j) % 2 == 0: 
                im[i, j] = 255 
    return im 
print(func(mat)) 
#    array([[ 255.,    0.,  255., ...,  255.,    0.,  255.], 
#        [   0.,  255.,    0., ...,    0.,  255.,    0.], 
#        [ 255.,    0.,  255., ...,  255.,    0.,  255.], 
#        ...,  
#        [ 255.,    0.,  255., ...,  255.,    0.,  255.], 
#        [   0.,  255.,    0., ...,    0.,  255.,    0.], 
#        [ 255.,    0.,  255., ...,  255.,    0.,  255.]]) 

请您参考如下方法:

我们将从零初始化数组开始。所以,这将是:np.zeros((heigh, width))。接下来,我们几乎没有办法用这种交替 255s 的模式来填充它。

方法#1:将开放范围数组与np.ogrid 结合使用模拟这些迭代器并利用 broadcasting 以矢量化方式直接转换比较-

I,J = np.ogrid[:h,:w] 
im[(I+J)%2==0] = 255 

方法 #2: 仔细观察,您似乎将每行中的所有其他元素设置为 255,从第一行的第一个元素开始,第二行第二行的元素和第三行的第一个元素等等。因此,我们可以使用 slicing也应该非常有效 -

im[::2,::2] = 255 
im[1::2,1::2] = 255 

运行时测试

方法-

def func(im): 
    h,w = im.shape 
    for i in range(h): 
        for j in range(w): 
            if (i + j) % 2 == 0: 
                im[i, j] = 255 
    return im 
 
def app1(im): 
    h,w = im.shape     
    I,J = np.ogrid[:h,:w] 
    im[(I+J)%2==0] = 255 
    return im 
 
def app2(im): 
    im[::2,::2] = 255 
    im[1::2,1::2] = 255 
    return im 

验证-

In [74]: im = np.random.randint(0,255,(1000,1000)) 
 
In [75]: im1 = im.copy() 
    ...: im2 = im.copy() 
    ...: im3 = im.copy() 
    ...:  
 
In [76]: func(im1) 
    ...: app1(im2) 
    ...: app2(im3) 
    ...:  
Out[76]:  
array([[255, 133, 255, ...,  14, 255,  41], 
       [235, 255, 191, ..., 255,  40, 255], 
       [255, 151, 255, ...,  51, 255,  18], 
       ...,  
       [ 50, 255, 177, ..., 255, 193, 255], 
       [255, 245, 255, ..., 114, 255,  27], 
       [223, 255, 148, ..., 255, 200, 255]]) 
 
In [77]: print np.allclose(im1,im2) 
    ...: print np.allclose(im1,im3) 
    ...:  
True 
True 

时间 -

In [78]: %timeit func(im) 
10 loops, best of 3: 106 ms per loop 
 
In [79]: %timeit app1(im) 
100 loops, best of 3: 14 ms per loop 
 
In [80]: %timeit app2(im) 
1000 loops, best of 3: 415 µs per loop 
 
In [82]: 106/0.415 # Speedup with approach #2 over original one 
Out[82]: 255.42168674698797