如何减少包含2个for循环的这段代码的运行时间?

时间:2019-10-10 20:23:10

标签: python image performance numpy for-loop

在下面的代码中,两个for循环平均大约需要0.05秒。 data是一个numpy数组。每个i,j单元格都包含一个元组,该元组保存这些函数定义的RGB值。稍后,我将使用这些RGB值构建图像,并且i, jx, y像素坐标。

有什么方法可以减少此操作的时间?还是通过指定每个像素的RGB值作为某种数学函数来构建图像的其他更快方法?

start = time.time()
for i in range (0, 150):
    for j in range(0, 150):
        data[i,j] = [int(math.sin(math.pi*i/300.0)*127.5 + 127.5),
                     int(math.cos(peak)*127.5 + 127.5),
                     int(math.sin(math.pi*j/300.0)*127.5 + 127.5)] 
print ('Time: ', time.time() - start)```

1 个答案:

答案 0 :(得分:3)

您可以使用ogrid在这里删除 all 个循环,而只需使用三个计算,一个用于rgb


x, y, z = data.shape
i, j = np.ogrid[:x, :y]

data[..., 0] = (np.sin(np.pi*i/300)*127.5 + 127.5).astype(int)
data[..., 1] = (np.cos(peak)*127.5 + 127.5).astype(int)
data[..., 2] = (np.sin(np.pi*j/300)*127.5 + 127.5).astype(int)

性能

def rgb_vectorized(x, y, peak=1):
    data = np.empty((x, y, 3), dtype=int)
    i, j = np.ogrid[:x, :y]
    data[..., 0] = (np.sin(np.pi*i/300)*127.5 + 127.5).astype(int)
    data[..., 1] = (np.cos(peak)*127.5 + 127.5).astype(int)
    data[..., 2] = (np.sin(np.pi*j/300)*127.5 + 127.5).astype(int)
    return data

def rgb_original(x, y, peak=1):
    data = np.empty((x, y, 3), dtype=int)
    for i in range (x):
        for j in range(y):
            data[i,j] = [int(math.sin(math.pi*i/300.0)*127.5 + 127.5),
                         int(math.cos(peak)*127.5 + 127.5),
                         int(math.sin(math.pi*j/300.0)*127.5 + 127.5)]
    return data

%timeit rgb_vectorized(1000, 1000)
9.85 ms ± 109 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit rgb_original(1000, 1000)
3.4 s ± 27.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

验证

>>> np.array_equal(rgb_vectorized(1000, 1000), rgb_original(1000, 1000))
True