2017-05-31 48 views
1

我写了一个函数来通过for循环生成示例numpy数组。但是对于较大的维度而言太慢了。高效创建0和255的棋盘图案

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.]]) 

回答

4

我们将从零初始数组开始。那么,那将是: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 
1

您还可以使用tile来重复模式,如你的。

import numpy as np 
n = 5 
x = np.tile(np.array([[0,255],[255,0]]),(n,n)) 
2

您可以使用numpy数组的奇特索引属性。

但这正是你所需要的一个例子是:

import numpy as np 
arr = np.zeros((10, 10)) 
a = np.arange(0, 10, 2) 
b = np.arange(1, 10, 2) 
arr[a[:, None], a[None, :]] = 255 
arr[b[:, None], b[None, :]] = 255 

print(arr) 
array([[ 255., 0., 255., ..., 0., 255., 0.], 
     [ 0., 255., 0., ..., 255., 0., 255.], 
     [ 255., 0., 255., ..., 0., 255., 0.], 
     ..., 
     [ 0., 255., 0., ..., 255., 0., 255.], 
     [ 255., 0., 255., ..., 0., 255., 0.], 
     [ 0., 255., 0., ..., 255., 0., 255.]])