簡體   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