如何在Python中快速求和多个数组中的一系列索引?

How to quickly sum a range of indexes in multiple arrays in Python?

我正在尝试使用一个方程重建 HDR 图像,其中我必须对每个 i 值的分子和分母中的 j 个值 (0-15) 求和。有没有更快的方法来做到这一点?也许使用 np.sum?

g 是一个 255 长的一维数组,它重新映射所有像素值。

lEks 是 15 张图像的对数曝光时间

Z 是一个大小为 [95488, 15] 的数组,第一维是像素索引,第二维是图像编号

def genHDR(Z,g,lEks):

    Zi, Zj = Z.shape        #[95488, 15]
    HDRimage= np.zeros(Zi)

    for i in range(Zi):
        numerator   = 0
        denominator = 0

        for j in range(Zj):
            numerator   +=(Z[i,j])*(g[Z[i,j]] - lEks[j])
            denominator +=(Z[i,j])

        HDRimage[i] = numerator/denominator
    return HDRimage

可能最好的方法是使用 np.Array.sum(axis=1)。假设 g(Z[i,j]) 调用有效。实际上你甚至不需要任何循环:

import numpy as np

Z = np.random.randint(0,255,(10,15))
g=np.random.randint(0,10,(256))
lEks = np.random.rand((15))

def genHDR(Z,g,lEks):
    numerator = (Z*(g[Z]-lEks.view().reshape((1,)+ lEks.shape))).sum(axis=1)
    denominator = Z.sum(axis=1)
    HDRimage = numerator/denominator
    return HDRimage

@Dillman 先于我。也许您仍然可以使用下面的内容来了解​​如何构建它。我喜欢分步思考。

import numpy as np

Z=  np.random.randint(low=0,high=256,size=(6,3))   # assume just 3 images with 6 pixels each
print(f' Z= {Z}')

lEks=np.random.rand(3)
print(f'lEks = {lEks}')

g0=np.arange(255)   #some example mapping; here from byte to half byte
g= g0//2        # // integer division


npxl,nimage=np.shape(Z)
print(f'npxl={npxl} nimage={nimage}')

# vectorize just one operation at first, easier to visualize
hdr=np.zeros(npxl)

for i in np.arange(npxl):
    #print(Z[i])
    denom=np.sum(Z[i])
    hdr[i]= np.sum(Z[i] *(g[Z[i]]- lEks))/denom 
    # Z[i] is just a vector of length 3, just like lEks

print(hdr)

# this would do it, but still be slower than necessary, as your remaining loop has many more elements that 
# the one we dealt with


# now vectorize the other coordinate (remove the remaining for-loop)
hdr=np.zeros(npxl)
hdr=  np.sum(Z *(g[Z]- lEks), axis=1)/ np.sum(Z,axis=1)   # which axis to sum over is critical
print(hdr)

#final code

def genHDR(Z, g, lEks):
    npxl,nimage=np.shape(Z)
    hdr=np.zeros(npxl)
    hdr=  np.sum(Z *(g[Z]- lEks), axis=1)/ np.sum(Z,axis=1) 
    return hdr


print(genHDR(Z,g,lEks))

输出:

 Z= [[199 101  67]
 [134  16 137]
 [219   5 135]
 [153  19  17]
 [238  41 120]
 [ 93  50 179]]
lEks = [0.57778608 0.18113957 0.85257974]
npxl=6 nimage=3
[72.94714613 63.50130665 91.04028102 62.58551969 90.46303414 65.97390417]
[72.94714613 63.50130665 91.04028102 62.58551969 90.46303414 65.97390417]
[72.94714613 63.50130665 91.04028102 62.58551969 90.46303414 65.97390417]