【问题标题】:Speed performance improvement needed. Using nested for loops需要提高速度性能。使用嵌套的 for 循环
【发布时间】:2014-01-17 23:15:25
【问题描述】:

我有一个形状为 (1002,1004) 的二维数组。对于这个问题,它可以通过以下方式生成:

a = numpy.arange( (1002 * 1004) ).reshape(1002, 1004)

我所做的是生成两个列表。列表通过以下方式生成:

theta = (61/180.) * numpy.pi
x = numpy.arange(a.shape[0])             #(1002, )
y = numpy.arange(a.shape[1])             #(1004, )

max_y_for_angle = int(y[-1] - (x[-1] / numpy.tan(theta)))

第一个列表由以下给出:

x_list = numpy.linspace(0, x[-1], len(x))

请注意,此列表与 x 相同。但是,为了便于说明和提供清晰的图片,我声明了这个“列表”。

我现在要做的是创建一个与 x_list 一样长的 y_list。我想使用这些列表来确定我的二维数组中的元素。在确定并存储元素的总和后,我想将 y_list 移动 1 并再次确定元素的总和。我想为 max_y_for_angle 迭代执行此操作。我的代码是:

sum_list = numpy.zeros(max_y_for_angle)
for idx in range(max_y_for_angle):
    y_list = numpy.linspace((len(x) / numpy.tan(theta)) + idx, y[0] + idx , len(x))
    elements = 0
    for i in range(len(x)):
       elements += a[x_list[i]][y_list[i]]
    sum_list[idx] = elements

此操作有效。然而,正如人们想象的那样,由于 for 循环中的 for 循环,这需要花费大量时间。 for 循环的迭代次数也无济于事。我怎样才能加快速度?该操作现在大约需要 1 秒。我正在寻找低于 200 毫秒的东西。

当输入为 x_list 和 y_list 时,是否有可能返回二维数组元素的列表?我尝试了以下方法,但这不起作用:

a[x_list][y_list]

非常感谢!

【问题讨论】:

  • 只有我一个人,还是xy完全没用?
  • 我同意我可以将 1002 和 1004 用于我的目的。但是,由于创建 xy 几乎不需要任何时间,我确实创建它们以获得更清晰的画面。至少对我自己而言
  • 也让代码更通用。如果二维数组的形状发生变化,它仍然可以工作
  • 除了...您可以直接使用数组的形状。无需为此制作额外的数组。

标签: python arrays performance for-loop numpy


【解决方案1】:

通过a[x, y] 可以返回一个数组 元素组成的二维数组,其中xy 都是整数数组。这称为高级索引或有时称为fancy indexing。在您的问题中,您提到了很多列表,但实际上从未在代码中使用任何列表, x_list 和 y_list 都是数组。此外,即使ij 是整数值,numpy 多维数组通常也会被索引为a[i, j]

使用花哨的索引和一些清理代码产生了这个:

import numpy

def line_sums(a, thata):
    xsize, ysize = a.shape
    tan_theta = numpy.tan(theta)
    max_y_for_angle = int(ysize - 1 - ((xsize - 1) / tan_theta))

    x = numpy.arange(xsize)
    y_base = numpy.linspace(xsize / tan_theta, 0, xsize)
    y_base = y_base.astype(int)
    sum_list = numpy.zeros(max_y_for_angle)

    for idx in range(max_y_for_angle):
        sum_list[idx] = a[x, y_base + idx].sum()

    return sum_list

a = numpy.arange( (1002 * 1004) ).reshape(1002, 1004)
theta = (61/180.) * numpy.pi
sum_list = line_sums(a, theta)

希望对您有所帮助。

【讨论】:

  • 这就像一个魅力,只需要大约 20 毫秒!非常感谢!
猜你喜欢
  • 2012-11-25
  • 2021-12-01
  • 2019-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-29
  • 2014-07-27
  • 1970-01-01
相关资源
最近更新 更多