![](/img/trans.png)
[英]Efficient mapping of a function with multiple arguments along an axis of an ndarray
[英]Applying a mapping function to each member of an ndarray with indices as arguments
我有一個ndarray表示形狀為(width,height,3)的RGB圖像,我希望用自身的某些功能,其位置和所屬顏色通道的結果替換每個值。 在三個嵌套的for循環中這樣做非常慢,有沒有辦法將其表示為本地數組操作?
編輯:尋找就地解決方案-一種不涉及創建另一個O(width x height)ndarray的解決方案(除非numpy具有某種魔術作用,可以阻止這種ndarray的實際分配)
我不確定您的問題是否正確! 我了解到的是,您希望基於RGB圖像的每個通道的對應索引對其應用映射,如果是這樣,則MIGHT下面的代碼會有所幫助,因為您的問題中沒有可用的詳細信息。
import numpy as np
bit_depth = 8
patch_size = 32
def lut_generator(constant_multiplier):
x = np.arange(2 ** bit_depth)
y = constant_multiplier * x
return dict(zip(x, y))
rgb = np.random.randint(0, (2**bit_depth), (patch_size, patch_size, 3))
# Considering a simple lookup table without using indices.
lut = lut_generator(5)
# splitting three channels followed and their respective indices.
# You can use indexes wherever you need them.
r, g, b = np.dsplit(rgb, rgb.shape[-1])
indexes = np.arange(rgb.size).reshape(rgb.shape)
r_idx, g_idx, b_idx = np.dsplit(indexes, indexes.shape[-1])
# Apply transformation on each channel.
transformed_r = np.vectorize(lut.get)(r)
transformed_g = np.vectorize(lut.get)(g)
transformed_b = np.vectorize(lut.get)(b)
祝好運!
注意許多注釋中的限定條件,直接使用numpy算術通常會更容易,更快捷。
import numpy as np
def test(item, ix0, ix1, ix2):
# A function with the required signature. This you customise to suit.
return item*(ix0+ix1+ix2)//202
def make_function_for(arr, f):
''' where arr is a 3D numpy array and f is a function taking four arguments.
item : the item from the array
ix0 ... ix2 : the three indices
it returns the required result from these 4 arguments.
'''
def user_f(ix0, ix1, ix2):
# np.fromfunction requires only the three indices as arguments.
ix0=ix0.astype(np.int32)
ix1=ix1.astype(np.int32)
ix2=ix2.astype(np.int32)
return f(arr[ix0, ix1, ix2], ix0, ix1, ix2)
return user_f
# user_f is a function suitable for calling in np.fromfunction
a=np.arange(100*100*3)
a.shape=100,100,3
a[...]=np.fromfunction(make_function_for(a, test), a.shape)
我的測試功能非常簡單,因此我可以在numpy中進行。
使用from函數:
%timeit np.fromfunction(make_function_for(a, test), a.shape)
5.7 ms ± 346 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
使用numpy算法:
def alt_func(arr):
temp=np.add.outer(np.arange(arr.shape[0]), np.arange(arr.shape[1]))
temp=np.add.outer(temp,np.arange(arr.shape[2]))
return arr*temp//202
%timeit alt_func(a)
967 µs ± 4.94 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
因此,在這種情況下,numpy算術在我的計算機上幾乎快6倍。
編輯糾正我看似不可避免的錯別字!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.