簡體   English   中英

以索引為參數將映射函數應用於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.

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