以索引为参数将映射函数应用于ndarray的每个成员

时间:2018-12-17 16:05:08

标签: python numpy numpy-ndarray

我有一个ndarray表示形状为(width,height,3)的RGB图像,我希望用自身的某些函数,其位置和所属颜色通道的结果替换每个值。在三个嵌套的for循环中这样做非常慢,有没有办法将其表示为本地数组操作?

编辑:寻找就地解决方案-一种不涉及创建另一个O(width x height)ndarray的解决方案(除非numpy具有某种魔术作用,可以阻止这种ndarray的实际分配)

2 个答案:

答案 0 :(得分:0)

我不确定您的问题是否正确!据我了解,您想根据其相应索引在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)

祝你好运!

答案 1 :(得分:0)

请注意许多注释中的限定条件,直接使用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来完成。

使用功能:

%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倍。

编辑以纠正我看似不可避免的错字!