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次!