繁体   English   中英

使用Numpy优化Python中的数组操作

[英]Optimizing array operations in Python with Numpy

我很困惑。 我只是将我的代码从Java移植到Python。 商品新闻是我使用的lib的Python替代品更快。 不好的是我的自定义处理代码比我写的Python替代要慢得多:(我甚至删除了一些我认为不必要的部分,仍然慢得多.Java版本花了大约半秒钟,Python需要5-6。

rimg1 = imageio.imread('test1.png').astype(np.uint8)
rimg2 = imageio.imread('test2.png').astype(np.uint8)

sum_time = 0
for offset in range(-left, right):
    rdest = np.zeros((h, w, 3)).astype(np.uint8)

    if offset == 0:
        continue

    mult = np.uint8(1.0 / (offset * multiplier / frames))
    for y in range(h):
        for x in range(0, w - backup, 1):
            slice_time = time.time()
            src = rimg2[y,x] // mult + 1
            sum_time += time.time() - slice_time

            pix = rimg1[y,x + backup]

w~ = 384和h~ = 384 src通常为0-30。 从左到右是-5到5

sum_time怎么花费我总时间的三分之一?

编辑

在josephjscheidt的帮助下,我做了一些改变。

mult = np.uint8(1.0 / (offset * multiplier / frames))
multArray = np.floor_divide(rimg2, mult) + 1
for y in range(h):
    pixy = rimg1[y]
    multy = multArray[y]
    for x in range(0, w - backup, 1):
        src = multy[y]
        slice_time = time.time()
        pix = pixy[x + backup]
        sum_time += time.time() - slice_time
        ox = x
        for o in range(src):
            if ox < 0:
                break

            rdest[y,ox] = pix
            ox-=1

使用srcArray的numpy迭代器将总时间减少了近一半! numpy操作本身似乎花费的时间可以忽略不计。

现在大部分时间都是在rimg1查找中

pix = rimg1[x + backup]

内部for循环(两者占用50%的时间)。 是否有可能通过numpy操作来处理这个问题?

编辑

我想重写它可能是有益的,但不知何故,以下实际上需要更长一点:

    for x in range(0, w - backup, 1):
        slice_time = time.time()
        lastox = max(x-multy[y], 0)
        rdest[y,lastox:x] = pixy[x + backup]
        sum_time += time.time() - slice_time

编辑

            slice_time = time.time()
            depth = multy[y]
            pix = pixy[x + backup]

            ox = x

            #for o in range(depth):
            #    if ox < 0:
            #        break;
            #
            #    rdesty[ox] = pix
            #    ox-=1

            # if I uncomment the above lines, and comment out the following two
            # it takes twice as long!
            lastox = max(x-multy[y], 0)
            rdesty[lastox:x] = pixy[x + backup]

            sum_time += time.time() - slice_time

python解释器很奇怪..

sum_time现在花费的时间是2.5秒。 相比之下,Java在60ms内完成

对于numpy数组而言,for循环非常慢,并且这里有一个三层for循环。 numpy数组的基本概念是一次对整个数组执行操作,而不是尝试迭代它们。

虽然我无法完全解释您的代码,因为大多数变量在您提供的代码块中未定义,我相当有信心您可以在这里重构并向量化您的命令以删除循环。 例如,如果将偏移重新定义为一维数组,则可以一次计算mult的所有值,而无需调用for循环:mult将成为保持正确值的一维数组。 我们可以使用out参数(将默认输出设置为偏移数组)和where参数(仅在offset不等于零的情况下执行计算)来避免除以零:

mult = np.uint8(np.divide(1.0, (offset * multiplier / frames),
                          out = offset, where = (offset != 0))

然后,要逐行使用rimg2上的mult数组,你可以使用广播技巧(这里,我假设你想在rimg2中为每个元素添加一个):

src = np.floor_divide(rimg2, mult[:,None], out = rimg2, where = (mult != 0)) + 1

在学习如何有效地使用numpy数组时,我发现这篇文章非常有用:

https://realpython.com/numpy-array-programming/

由于您正在处理图像,因此您可能需要特别注意有关图像特征提取和stride_tricks的部分。 无论如何,我希望这可以帮助你开始。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM