Python 找到最近的向量

Python 找到最近的向量,python,optimization,Python,Optimization,最近我写了一个RGB图像量化算法。每个像素由(R,G,B)向量表示,量化码本是一对三维向量。图像的每个像素都需要映射到(例如,“替换为”)欧几里德距离(更准确地说,是平方欧几里德距离)最近的码本像素。 我是这样做的: class EuclideanMetric(DistanceMetric): def __call__(self, x, y): d = x - y return sqrt(sum(d * d, -1)) class Quantizer(o

最近我写了一个RGB图像量化算法。每个像素由(R,G,B)向量表示,量化码本是一对三维向量。图像的每个像素都需要映射到(例如,“替换为”)欧几里德距离(更准确地说,是平方欧几里德距离)最近的码本像素。 我是这样做的:

class EuclideanMetric(DistanceMetric):
    def __call__(self, x, y):
        d = x - y
        return sqrt(sum(d * d, -1))

class Quantizer(object):
    def __init__(self, codebook, distanceMetric = EuclideanMetric()):
        self._codebook = codebook
        self._distMetric = distanceMetric

    def quantize(self, imageArray):
        quantizedRaster = zeros(imageArray.shape)

        X = quantizedRaster.shape[0]
        Y = quantizedRaster.shape[1]
        for i in xrange(0, X):
            print i
            for j in xrange(0, Y):
                dist = self._distMetric(imageArray[i,j], self._codebook)
                code = argmin(dist)
                quantizedRaster[i,j] = self._codebook[code]

        return quantizedRaster
…在我的Pentium Core Duo 2.2 GHz、4 Gig内存和2600*2700像素的图像上,它的工作时间长达800秒:(

有没有一种方法可以对此进行某种程度的优化?可能是其他算法或某些特定于Python的优化


UPD:我尝试使用平方欧几里德函数,但仍然获得了大量的时间。

你可以使用矢量量化函数
vq

一个简单的优化是放弃
sqrt
调用。x与sqrt(x)是单调的,因为您不需要实际距离,只需要最小距离,所以请使用x^2。由于sqrt比较昂贵,应该会有所帮助

在处理距离时经常使用此技巧。例如,如果有距离阈值,则可以使用阈值^2并在距离计算中删除sqrt。实际上,只有在需要绝对距离时才需要sqrt。对于相对距离,请删除sqrt

更新:当时可能需要更改算法。现在,您正在将每个码本向量与每个像素进行比较。这将加快速度,以减少距离计算的数量


对于这一点,使用a可能会做得更好,这将减少对每个像素的搜索,从O(代码本)到O(日志(代码本))。我从来没有在python中这样做过,但是一些Google提供了一个可能会工作的实现。

如果
X
非常大,那么你会大量打印
I
,这可能会影响性能。要获得不太具体的答案,请继续阅读

为了找出流程中的瓶颈在哪里,我建议使用计时装饰器,类似于

from functools import wraps
import time

def time_this(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        finish = time.time()
        elapsed = (finish - start) * 1000
        print '{0}: {1} ms'.format(func.__name__, elapsed)
        return result
    return wrapper
我曾经在某个地方发现过这个函数,并且总是用它来找出我的代码的速度慢的地方。你可以把你的算法分解成一系列单独的函数,然后用这个decorator来修饰函数,看看每个函数调用需要多长时间。然后就是在哪些函数中摆弄哪些语句,看看它们是什么at提高了修饰函数运行所需的时间。您主要关注两件事:1)执行时间较长的语句,或2)执行时间不一定很长的语句,但执行次数太多,以至于性能上的微小改进会对整体性能产生很大影响


祝你好运

之前错过了这个细节:你说“码本是一对三维向量”,你的字面意思是2吗?如果是这样的话,它会一直是2还是仅仅用于测试?我的意思是“三维”。可能还有更多(我正在分析陆地卫星照片),但由于算法的性能在添加新尺寸时呈线性下降,因此可以使用其中3个尺寸进行测试。打印并不会真正影响性能,我已经检查过了。对于评测,我使用cProfiler和pstats模块。我必须检查这些评测模块。谢谢你的指点。接受!分析表明,计算距离几乎需要所有的开销时间。这就是瓶颈。如果有办法在函数中使用欧几里得之外的距离度量,我肯定已经在使用它了。我正在写一个学位,需要比较一些指标来选择准确的、计算上比较轻松的指标。