【问题标题】:Faster way to access 2D lists/arrays and do calculations in Python?访问 2D 列表/数组并在 Python 中进行计算的更快方法?
【发布时间】:2013-08-28 17:46:48
【问题描述】:

我正在运行 2 个嵌套循环(第一个 120 次运行,第二个 500 次运行)。 在大多数 120x500 运行中,我需要访问多个列表和列表中的列表(我将它们称为 2D 数组)。

目前 120x500 运行大约需要 4 秒。大多数时间都花在了三个列表追加和几个二维数组访问上。 数组是由我在循环之外预填充的。

这是我的代码:

    #Range from 0 to 119
    for cur_angle in range(0, __ar_angular_width-1):

        #Range from 0 to 499
        for cur_length in range(0, int(__ar_length * range_res_scale)-1):

            v_x = (auv_rot_mat_0_0*self.adjacent_dx[cur_angle][cur_length])+(auv_rot_mat_0_1*self.opposite_dy[cur_angle][cur_length])
            v_y = (auv_rot_mat_1_0*self.adjacent_dx[cur_angle][cur_length])+(auv_rot_mat_1_1*self.opposite_dy[cur_angle][cur_length])

            v_x_diff = (v_x+auv_trans_x) - ocp_grid_origin_x
            v_y_diff = (v_y+auv_trans_y) - ocp_grid_origin_y

            p_x = (m.floor(v_x_diff/ocp_grid_resolution))
            p_y = (m.floor(v_y_diff/ocp_grid_resolution))

            data_index = int(p_y * ocp_grid_width + p_x)

            if data_index >= 0 and data_index < (len(ocp_grid.data)-1):
                probability = ocp_grid.data[data_index]

                if probability == 100:
                    if not m.isnan(self.v_directions[cur_angle]):
                        magnitude = m.pow(probability, 2) * self.magnitude_ab[cur_length]

                        ov_1 = self.v_directions[cur_angle]
                        ov_2 = magnitude
                        ov_3 = self.distances[cur_length]

                        obstacle_vectors.append(ov_1)
                        obstacle_vectors.append(ov_2)
                        obstacle_vectors.append(ov_3)

我试图通过 time.time() 和构建差异来计算处理时间,但它并不可靠。计算出来的时间波动很大。

我并不是真正的 Python 专业人士,因此欢迎任何建议。 任何想法如何使代码更快?

编辑: 数组的初始化是用这段代码完成的:

        self.adjacent_dx = [i[:] for i in [[0]*(length_iterations-1)]*(angular_iterations-1)]
        self.opposite_dy = [i[:] for i in [[0]*(length_iterations-1)]*(angular_iterations-1)]

【问题讨论】:

  • 不要直接使用time.time()来计时结果。将您的代码包装在特定函数中并使用timeit 模块。特别是在使用IPython 控制台及其%timeit 魔法时,它的配置非常简单。
  • 学习 NumPy 并使用它的向量化操作。
  • 感谢您的快速提示。我会研究一下timeit。不过,我不确定 NumPy,它不是只在大计算时更快吗?
  • 对于这种操作,NumPy 似乎需要比 python 列表多 2-10 倍。我认为 NumPy 仅适用于更大、更复杂的操作。

标签: python arrays performance list


【解决方案1】:

一些一般提示:

  1. 尽量优化算法。
  2. 如果可能,请使用PyPy 而不是常规的 Python。如果您的所有外部依赖项都可以使用,这通常不需要任何代码修改。
  3. 静态类型和编译到 C 可以增加额外的提升,但需要一些简单的代码修改。为此,您可以使用Cython

请注意,第 1 步通常很难完成且最耗时,如果您已经拥有良好的代码,则可以为您提供少量提升,而第 2 步和第 3 步则无需太多额外努力即可为您提供显着提升。

【讨论】:

  • 谢谢,我会看看这些可能性。该算法已经非常小,因此正如您所说,最好查看第 2 步和第 3 步。
猜你喜欢
  • 2018-03-04
  • 2020-07-07
  • 1970-01-01
  • 2012-09-09
  • 2023-03-14
  • 2020-12-14
  • 1970-01-01
  • 2020-07-02
  • 1970-01-01
相关资源
最近更新 更多