Python 使用numpy可以更快地实现这一点吗?
有一个彩色图像,一个形状Python 使用numpy可以更快地实现这一点吗?,python,numpy,Python,Numpy,有一个彩色图像,一个形状(h,w,3)的numpy数组,其中N=h*w像素;有一个数组标签的形状(h,w),每个标签是一个介于1和M之间的整数N是10^6-10^7,M是10^3-10^4 我需要生产 结果图像(h、w、3),其中标记为l的每个像素的颜色是标记为l的所有像素的平均颜色。即: def recolor1(image, labels): result = np.empty(shape=(h,w,3)) for label in np.unique(labels):
(h,w,3)
的numpy数组,其中N=h*w像素;有一个数组标签的形状(h,w)
,每个标签是一个介于1和M之间的整数N是10^6-10^7,M是10^3-10^4
我需要生产
结果图像(h、w、3),其中标记为l的每个像素的颜色是标记为l的所有像素的平均颜色。即:
def recolor1(image, labels):
result = np.empty(shape=(h,w,3))
for label in np.unique(labels):
mask = labels==label
mean = np.mean(image[mask], axis=0)
result[mask] = mean
return result
代码很简单,但运行时间为O(M.N)(mask
的计算时间为O(N),循环运行时间为M)
可以进行O(N)recolor2
。基本上,你需要对标签和图像像素进行两次检查。首先计算一个按标签索引的辅助数组,其中保存每个主数组的和以及该标签的像素数。然后计算每个标签的平均值。然后你们再次检查标签和像素,计算结果。求平均值的O(M)时间是噪声
使用Python编写的recolor2
,recolor1
和recolor2
在~4s处实现N=1000000和M=1000的盈亏平衡。正如所料,recolor1
的时间在M=5000时线性增长到~20s,而recolor2
的时间基本上保持不变
对于相对较小的图像,4s不是很好,对于较大的图像,4s会变得更差。我不是numpy和相关图书馆的专家。有O(N)解决方案吗?让我们试试
np.bincount
并在通道上循环:
result = np.stack([np.bincount(labels.flat, weights=img[...,i].flat)[labels-1]
for i in range(3)],
axis=-1)
在我的系统上使用h,w,M=10001000
大约需要35毫秒
注意这计算总和,但平均值应该很容易。有帮助吗?是的,这绝对是我要找的!工作在47毫秒内跑10007505000次!