【问题标题】:Speeding Up and Optimizing Python Loop加速和优化 Python 循环
【发布时间】:2019-09-11 03:54:09
【问题描述】:

在过去的几天里,我一直在碰壁,试图优化我的代码以提高速度。然而,这里的这段代码仍然很慢,我不太确定如何具体提高它的速度。

在使用速度测试时,问题似乎主要在于嵌套的 for 循环。计算距离的循环似乎比较快。

作为对代码的解释,我正在使用 openCV 读取图像,浏览该图像,并找到离给定位置最近的像素。我想在嵌套的 for 循环中忽略条件中的某些颜色,以及忽略代码中其他地方以前访问过的像素。

    found = False
    randArray = []
    for i in range(0,imgCol):
        for j in range(0,imgRow):
            if(pixelInLine[j*imgCol + i] == 0  and numpy.any(img2[j, i] != 0) and isWhite(j,i) == False):
                found = True
                temp = points(j,i)
                pointArray.append(temp)

                #The pixelsInLine is to ignore previously visited pixels
                #The rest of the above conditional is to ignore colors I don't want


    myDist = 0
    currDist = sys.maxsize
    distArray = []
    for sx in pointArray:
        myDist = math.sqrt( ((currR-sx.rr)**2)+((currC-sx.cc)**2))
        if myDist == currDist:
            distArray.append(sx)
        if myDist < currDist:
            distArray = []
            distArray.append(sx) 
            currDist = myDist

    if found == True:
        rrr = distArray[0].rr
        ccc = distArray[0].cc

【问题讨论】:

  • 你可能想在遇到 if 条件后打破循环,找到 = True ?
  • 我过去做过,是的,速度要快得多。这是个好主意,我很欣赏它,但它只是在循环中找到第一个可用像素。这不是我真正想要的功能。我想找到最近的像素,一个接近的像素,或者至少是一种比从左到右从上到下找到第一个开放点更有机的算法。
  • 应该可以迁移到 CodeReview 站点,但我无法标记该站点。

标签: python python-3.x performance optimization


【解决方案1】:

很难准确说出发生了什么,但我的理解是,您正在尝试找到满足某些属性并且与其他像素具有最小欧几里得距离的像素集。如果是这样的话,与其测试数组中的每一个像素,为什么不从最近的像素开始呢?如果/当您找到满足所需属性的那些时,您可以停止搜索,因为您知道没有更接近的。

【讨论】:

  • 有趣,我以前没有想过这样的事情,我很感激。我不能 100% 确定实现的外观,主要是因为我从 openCV 获取图像数组并按距离排序并不会马上出现。我会做一些研究,看看我能不能让它工作。
  • > 按距离排序 - 这只是定义一个返回与您的固定点的欧几里得距离的函数的问题,我们称之为a:def func(b): return math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2)。然后你可以像这样使用函数:sorted_pixels = sorted(array_of_pixels, key=func)。请注意,您可以根据需要删除 math.sqrt,因为它不会影响排序顺序。
  • 您有n^2 像素,因此对它们进行排序是O(n^2 log n),它比O(n^2)
  • @OneLyner 哎呀,你完全正确。将更新我的答案以删除排序部分。 (还有其他方法可以先检查最近的像素。)
【解决方案2】:

如果您对多个像素执行此操作,则带有条件的部分不取决于您当前正在查看的像素。 一种改进是只选择一次O(n^2) 像素选择,然后在更新pixelInLine 时才更新它,例如

正如@mackorone 所注意到的,您还可以尝试从最近到最远的位置枚举像素。但这取决于您期望pointArray 是大还是小。如果它足够小,遍历所有这些可能比花哨的枚举要快。

【讨论】:

    猜你喜欢
    • 2020-01-19
    • 2013-07-17
    • 1970-01-01
    • 2020-11-07
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 2018-12-27
    • 2014-06-07
    相关资源
    最近更新 更多