[英]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.