首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >4用于循环优化

4用于循环优化
EN

Stack Overflow用户
提问于 2019-05-23 02:12:36
回答 1查看 78关注 0票数 0

我有以下这些极其丑陋的代码:

代码语言:javascript
复制
def cell_hist(gradients):
    h, w, d  = gradients.shape
    window_size = 8
    res_h = int(h / window_size)
    res_w = int(w / window_size)
    bins_number = 9
    bin_width = (180 / bins_number)
    bins = [bin_width * x for x in range(bins_number)]
    result = np.zeros((res_h, res_w, bins_number))

    for a in range(res_h):
        for b in range(res_w):
            fragment = gradients[a*window_size:(a+1)*window_size, b*window_size:(b+1)*window_size]
            hist = np.zeros(bins_number)

            for row in fragment:
                for pixel in row:
                    nbin = int((pixel[1] // bin_width) % 9)
                    hist[nbin] += ((pixel[1] - bins[nbin]) / bin_width) * pixel[0]
                    if nbin != bins_number - 1:
                        hist[nbin+1] += ((bins[nbin+1] - pixel[1]) / bin_width) * pixel[0]
                    else:
                        hist[0] += ((180 - pixel[1]) / bin_width) * pixel[0]
            result[a,b] = hist
    return result

我知道这很糟糕,但是我想不出有什么优化方法可以去掉4个for循环。有没有什么技巧的numpy索引可能会对这里有所帮助?如果你能帮助我,我将非常感激!

梯度参数是一个看起来像这样的矩阵:(w,h,2)。所以基本上是两个通道的图像。

EN

回答 1

Stack Overflow用户

发布于 2019-05-23 02:31:01

通过itertools和嵌套元素的组合,有一些方法可以减少“选项卡式内部”。

但在我看来,没有办法正确地做到这一点。

首先,让我们考虑一下你能做些什么,把这个庞大的代码分成几个函数,在必要时相互调用,然后给任何函数/部分命名,使它不仅不那么难看,而且可读性更好:)

例如,我将把它分成如下几部分:

代码语言:javascript
复制
def cell_hist(gradients):
    h, w, d  = gradients.shape
    window_size = 8
    res_h = int(h / window_size)
    res_w = int(w / window_size)
    bins_number = 9
    bin_width = (180 / bins_number)
    bins = [bin_width * x for x in range(bins_number)]
    result = np.zeros((res_h, res_w, bins_number))

    for a in range(res_h):
        for b in range(res_w):
            result[a,b] = func2(a, b)

    return result

def func2(a, b):
    fragment = gradients[a*window_size:(a+1)*window_size, b*window_size:(b+1)*window_size]
    hist = np.zeros(bins_number)

    for row in fragment:
        for pixel in row:
            nbin = int((pixel[1] // bin_width) % 9)
            hist[nbin] += ((pixel[1] - bins[nbin]) / bin_width) * pixel[0]
            if nbin != bins_number - 1:
                hist[nbin+1] += ((bins[nbin+1] - pixel[1]) / bin_width) * pixel[0]
            else:
                hist[0] += ((180 - pixel[1]) / bin_width) * pixel[0]
    return hist

但有许多变量你必须传递给它,然后最有效的方法来保持它的简单性。将它放在某个类中,这给了你简单的方法来记住self.中的变量,同时保持代码的清晰度,哪些是必需的,哪些不是:)

换行符对于可读性也很有用,请检查它:https://doingmathwithpython.github.io/breaking-long-lines-in-python.html

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56262695

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档