如何在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]
我正在尝试使用一个方程重建 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]