WBM*_*WBM 11 python performance for-loop numpy equality
这段代码的先决条件的细节很长,所以我会尽力总结.WB/RG/BYColor是基本图像,FIDO是应用于此基本图像的叠加.S_wb/rg/by是最终输出图像.WB/RG/BYColor与FIDO的大小相同.
对于FIDO中的每个唯一元素,我们希望计算基础图像中该区域的平均颜色.下面的代码执行此操作,但由于numFIDO非常大(最多40,000),这需要很长时间.
计算三个独立RGB通道的平均值.
sX=200
sY=200
S_wb = np.zeros((sX, sY))
S_rg = np.zeros((sX, sY))
S_by = np.zeros((sX, sY))
uniqueFIDOs, unique_counts = np.unique(FIDO, return_counts=True)
numFIDOs = uniqueFIDOs.shape
for i in np.arange(0,numFIDOs[0]):
Lookup = FIDO==uniqueFIDOs[i]
# Get average of color signals for this FIDO
S_wb[Lookup] = np.sum(WBColor[Lookup])/unique_counts[i]
S_rg[Lookup] = np.sum(RGColor[Lookup])/unique_counts[i]
S_by[Lookup] = np.sum(BYColor[Lookup])/unique_counts[i]
Run Code Online (Sandbox Code Playgroud)
运行大约需要7.89秒,不会这么长,但这将包含在另一个循环中,所以它会累积起来!
我尝试过矢量化(如下所示),但我无法做到
FIDOsize = unique_counts[0:numFIDOs[0]:1]
Lookup = FIDO ==uniqueFIDOs[0:numFIDOs[0]:1]
S_wb[Lookup] = np.sum(WBColor[Lookup])/FIDOsize
S_rg[Lookup] = np.sum(RGColor[Lookup])/FIDOsize
S_by[Lookup] = np.sum(BYColor[Lookup])/FIDOsize
Run Code Online (Sandbox Code Playgroud)
数组大小匹配错误
根据我的时间,这比原始方法快10倍.我测试了这些数组:
import numpy as np
sX=200
sY=200
FIDO = np.random.randint(0, sX*sY, (sX, sY))
WBColor = np.random.randint(0, sX*sY, (sX, sY))
RGColor = np.random.randint(0, sX*sY, (sX, sY))
BYColor = np.random.randint(0, sX*sY, (sX, sY))
Run Code Online (Sandbox Code Playgroud)
这是我定时的部分:
import collections
colors = {'wb': WBColor, 'rg': RGColor, 'by': BYColor}
planes = colors.keys()
S = {plane: np.zeros((sX, sY)) for plane in planes}
for plane in planes:
counts = collections.defaultdict(int)
sums = collections.defaultdict(int)
for (i, j), f in np.ndenumerate(FIDO):
counts[f] += 1
sums[f] += colors[plane][i, j]
for (i, j), f in np.ndenumerate(FIDO):
S[plane][i, j] = sums[f]/counts[f]
Run Code Online (Sandbox Code Playgroud)
可能是因为即使Python中的循环很慢,这也会减少数据的遍历.
请注意,如果存在少量唯一值,则原始版本会变得更快FIDO.对于大多数情况,这大致相同.
小智 3
这已经在 Scipy 中实现了,所以你可以这样做:
from scipy.ndimage.measurements import mean as labeled_mean
labels = np.arange(FIDO.max()+1, dtype=int)
S_wb = labeled_mean(WBColor, FIDO, labels)[FIDO]
S_rg = labeled_mean(RGColor, FIDO, labels)[FIDO]
S_by = labeled_mean(BYColor, FIDO, labels)[FIDO]
Run Code Online (Sandbox Code Playgroud)
这是假设FIDO包含相对较小的整数。如果不是这种情况,您可以通过 进行改造np.unique(FIDO, return_inverse=True)。
对于 200x200 图像并包含从 0 到 40,000 的随机整数,这个简单的代码比原始代码快约 1000 倍FIDO。
| 归档时间: |
|
| 查看次数: |
482 次 |
| 最近记录: |