簡體   English   中英

替換 for 循環以提高我的 python 腳本的速度

[英]Replace for loop to increase speed of my python script

我是 python 新手,所以要溫柔。 我想將名為“image”的 numpy.ndarray 的值映射到我存儲在名為“maps”的 numpy.ndarray 中的其他值。

我有以下簡短的腳本來執行此操作(在我的腳本圖像中顯然不僅僅是零):

import numpy as np
import time

maps = np.arange(1024)
image = np.zeros((3800,2560))
t0 = time.time()
for ii in range(len(maps)):
    image[image == ii] = maps[ii]
print('time = ' + str(np.round(time.time()-t0,3)))

結果:

time = 6.167

它做我想要的,但在我的代碼中我需要很多次,長話短說,它運行得很慢(通常每次調用大約 6 秒左右)。 有沒有直接的方法來提高這個速度? :) 我知道通常使用 for 循環是最糟糕的,但我想不出解決方法。

我正在使用 python 3.7.6

非常感謝您的耐心和幫助。 如果還有什么我忘記提及的可以幫助您找到解決方案,請告訴我。

馬庫斯

編輯

看起來我的第一個例子太籠統了,所以我在這里展示了一些更接近我所做的事情:

import numpy as np
import time

a=1.5
points = np.array([[-np.pi,-np.pi/a]
,[-2.0,-2/a]
,[0,0]
,[2.0,2/a]
,[np.pi,np.pi/a],])
# fit spline
spline = interp1d(points[:,0], points[:,1], kind='cubic')

colormap_values = np.linspace(-np.pi,np.pi,(2**10), endpoint=True)
colormap = spline(colormap_values)
np.place(colormap, colormap>np.pi, np.pi)
np.place(colormap, colormap<-np.pi, -np.pi)
maps = np.floor((1023)*(colormap+np.pi)/(2*np.pi))

im = np.random.randint(0,1023,size = (3800,2560))
image = im.astype('f')

t0 = time.time()
for ii in range(len(maps)):
    image[image == ii] = maps[ii]
print('time = ' + str(np.round(time.time()-t0,3)))

結果:

time = 6.547

再想一想,對於這個特定的例子,你可以去

result = maps[image]

更一般地,您可以使用scipy.ndimage.labelled_comprehension

from scipy.ndimage import labeled_comprehension
result = labeled_comprehension(
    image, None, None, maps.__getitem__, out_dtype=np.int, default=0
    ).reshape(image.shape)

這在我的機器上運行 17 毫秒,而不是原始代碼的 11.5 秒。

請注意, labelled_comprehension忽略零標簽。 如果maps[0] != 0 ,您可能需要增加原始數組的每個元素並相應地調整maps

@hilberts_drinking_problem ,這是一個快速示例,用於在更小的空間中查看發生了什么:

import numpy as np
import time

a=1.5
points = np.array([[-np.pi,-np.pi/a]
    ,[-2.0,-2/a]
    ,[0,0]
    ,[2.0,2/a]
    ,[np.pi,np.pi/a],])
# fit spline
spline = interp1d(points[:,0], points[:,1], kind='cubic')


colormap_values = np.linspace(-np.pi,np.pi,(2**10), endpoint=True)
colormap = spline(colormap_values)
np.place(colormap, colormap>np.pi, np.pi)
np.place(colormap, colormap<-np.pi, -np.pi)
maps = np.floor((1023)*(colormap+np.pi)/(2*np.pi))
maps =  maps.astype('int32')

# im = np.random.randint(0,1023,size = (3800,2560))
image = np.random.randint(0,1023,size = (5,3))
image1 = im

t0 = time.time()
for ii in range(len(maps)):
    image[image == ii] = maps[ii]
print('time = ' + str(np.round(time.time()-t0,3)))

t1 = time.time()
result = maps[im]
print('time2 = ' + str(np.round(time.time()-t1,3)))

print((image))
print((result))

結果:

time = 0.002
time2 = 0.0
[[509 543 509]
 [509 733 509]
 [651 723 509]
 [509 787 509]
 [509 603 509]]
[[372 618 705]
 [425 321 282]
 [773 483 510]
 [204 733 633]
 [812 596 720]]

所以這兩件事做的不一樣。 例如 result[0,2] 與 image[0,2] 不同。 但是更詳細地看它似乎我的代碼所做的也是不正確的。 我需要重新審視。 :) 謝謝你的幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM