如何在python中加速数组生成?

时间:2010-07-04 22:51:31

标签: python arrays matrix performance opencv

我想我需要使用numpy或其他一些库来足够快地填充这些数组,但我不太了解它。现在这个操作在四核英特尔PC上大约需要1秒钟,但我需要它尽可能快。任何帮助是极大的赞赏。谢谢!

import cv

class TestClass:

  def __init__(self):

    w = 960
    h = 540

    self.offx = cv.CreateMat(h, w, cv.CV_32FC1)
    self.offy = cv.CreateMat(h, w, cv.CV_32FC1)

    for y in range(h):
      for x in range(w):
        self.offx[y,x] = x
        self.offy[y,x] = y

6 个答案:

答案 0 :(得分:8)

我八岁(慢)计算机能够在127毫秒内创建一个与矩阵大小相同的列表列表。

C:\Documents and Settings\gdk\Desktop>python -m timeit "[[x for x in range(960)]
 for y in range(540)]"
10 loops, best of 3: 127 msec per loop

我不知道cv模块是什么以及它如何创建矩阵。但也许这是代码速度慢的原因。

Numpy可能会更快。创建一个(python int)1s数组:

C:\Documents and Settings\gdk\Desktop>python -m timeit -s "from numpy import one
s" "ones((960, 540), int)"
100 loops, best of 3: 6.54 msec per loop

您可以比较使用不同模块创建矩阵的时间,看看是否有改变的好处:timeit module

答案 1 :(得分:1)

你正在生成50万个整数并创建超过一百万个引用。我很高兴它只需要1秒钟。

如果你这么做很多,你应该考虑缓存结果的方法。

另外,在这样的情况下使用四核任何东西都无济于事,你正在执行一次只能在一个核心上执行的串行操作(即使你有线程,CPython也只能执行由于全局解释器锁定,一次执行一个纯Python线程。

答案 2 :(得分:1)

Numpy中与OpenCV python完全相同的代码是

import numpy as np
offsetx, offsety = np.meshgrid(range(960),range(540))

如果您正在使用Python,请考虑学习numpy的不同功能将极大地帮助您。 OpenCV函数也可以直接使用numpy数组。 Python中numpy的语法要比OpenCV好得多。

以下是我的i7中两个版本的时间

time python test.py

real    0m0.654s 
user    0m0.640s
sys 0m0.010s

我的版本:

time python test2.py

real    0m0.075s
user    0m0.060s
sys 0m0.020s

答案 3 :(得分:0)

如果您反复创建相同的矩阵,使用cv.SetData()初始化它可能会更快

答案 4 :(得分:0)

好吧,你至少可以使用xrange而不是range。范围创建所有这些数字的完整列表。 xrange通过1生成它们。由于您一次只使用它们一个,因此您不需要它们的列表。

答案 5 :(得分:0)

我并不完全明白你想要达到的目标。但这里有两个可能对您有帮助的具体示例和基准。他们都做同样的事情,用红色填充960x540图像(数组)。

slow.py使用for循环来填充数组

import cv2
import numpy as np

width, height = 960, 540
image = np.zeros((height, width, 3), np.uint8)
# Fill array with red
for y in range(height):
    for x in range(width):
        image[y, x] = (0, 0, 255)

cv2.imwrite('red.jpg', image)

运行时间

$ time python slow.py
real    0m2.240s
user    0m2.172s
sys 0m0.040s

fast.py使用numpy填充数组

import cv2
import numpy as np

width, height = 960, 540    
image = np.zeros((height, width, 3), np.uint8)
# Fill array with red
image[:] = (0, 0, 255)
cv2.imwrite('red.jpg', image)

运行时间

$ time python fast.py
real    0m0.134s
user    0m0.084s
sys 0m0.024s

使用numpy代替for循环几乎快17倍