【问题标题】:Making nested 'for' loops more pythonic使嵌套的“for”循环更加pythonic
【发布时间】:2017-08-20 22:28:53
【问题描述】:

我对 python 比较陌生,我想知道如何通过避免显式嵌套的“for”循环和使用 python 的隐式循环来提高以下效率。我正在处理图像数据,在这种情况下试图加快我的 k-means 算法。这是我正在尝试做的一个示例:

# shape of image will be something like 140, 150, 3
num_sets, rows_per_set, num_columns = image_values.shape

for set in range(0, num_sets):
    for row in range(0, rows_per_set):
        pos = np.argmin(calc_euclidean(rgb_[set][row], means_list)
        buckets[pos].append(image_values[set][row])

我今天所拥有的效果很好,但我想让它更有效率。

非常感谢您的反馈和建议。

【问题讨论】:

  • Python 的隐式循环是什么意思?你是指numpy数据结构的向量化操作吗?
  • 不确定你所说的python隐式循环是什么意思,但你可以通过使用xrange和`itertools.product`来避免多个for循环,如下所示:for set, row in itertools.product(xrange( 0, num_sets), xrange(0, rows_per_set))
  • 嗨...感谢 cmets。在这种情况下,我指的是矢量化操作。我的想法是让数据处理运行得更快。 “for”循环是一种蛮力,我一直在寻找有关矢量化的建议以使其更有效。

标签: python loops nested vectorization


【解决方案1】:

这是一个矢量化解决方案。我几乎可以肯定我把你的尺寸弄糊涂了(3 并不是真正的列数,是吗?),但无论如何原则应该是可以识别的:

为了演示,我只将(平面)索引收集到桶中的集合和行中。

import numpy as np

k = 6
rgb_=np.random.randint(0, 9, (140, 150, 3))
means_list = np.random.randint(0, 9, (k, 3))

# compute distance table; use some algebra to leverage highly optimised
# dot product
squared_dists = np.add.outer((rgb_*rgb_).sum(axis=-1),
                             (means_list*means_list).sum(axis=-1)) \
    - 2*np.dot(rgb_, means_list.T)
# find best cluster
best = np.argmin(squared_dists, axis=-1)

# find group sizes
counts = np.bincount(best.ravel())
# translate to block boundaries
bnds = np.cumsum(counts[:-1])
# group indices by best cluster; argpartition should be
# a bit cheaper than argsort
chunks = np.argpartition(best.ravel(), bnds)
# split into buckets
buckets = np.split(chunks, bnds)

# check

num_sets, rows_per_set, num_columns = rgb_.shape

def calc_euclidean(a, b):
    return ((a-b)**2).sum(axis=-1)

for set in range(0, num_sets):
    for row in range(0, rows_per_set):
        pos = np.argmin(calc_euclidean(rgb_[set][row], means_list))
        assert pos == best[set, row]
        assert rows_per_set*set+row in buckets[pos]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-06
    • 1970-01-01
    相关资源
    最近更新 更多