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