【问题标题】:optimization of filtering a large data array过滤大数据数组的优化
【发布时间】:2021-10-11 02:30:59
【问题描述】:

我目前正在尝试通过解决一些示例问题来提高我的 Python 技能。其中之一是关于检查网格点是否位于障碍物后面。输出是不在障碍后面的所有网格点的数量。 给定的Hint是计算方向到点的角度,并与障碍物左右两侧的角度进行比较。 我的代码可以工作并给出正确的结果,但是对于大型网格 (1000x1000),它非常慢,所以我想知道是否有办法让代码更快。

花费时间最长的部分是检查一个点是否在障碍物后面,所以我在这里只包含这部分代码。如果您还需要其余代码,我很乐意将其包含在内:)

import math
import numpy as np


def CheckIfObstacle(point, Obstacle):

    for obs in Obstacle:

        # condition for a point being behind a barrier that is on positive side of Grid
        if obs[0]>0 and point[0] >= obs[0] and (obs[1] >= point[1] >= obs[2]):
                return True

        # condition for a point being behind a barrier that is on negative side of Grid
        elif obs[0]<0 and point[0] <=obs[0] and (obs[1]>= point[1]>= obs[2]):
                return True

    return False    


Obstacle = [] #[(y1,angle_big1,angle_small1),(y2,angle_big2,angle_small2),...]
for i in range(2,nObs+2):
   some code that puts data in Obstacle
    
Grid = calcGrid(S)  # [(y1,angle1),(y2,angle2),...]

count = 0
p=0
for point in Grid:
    if p%10000==0:
        print(round(p/len(Grid)*100,3),'%')
    p+=1
    if CheckIfObstacle(point, Obstacle) ==False:
        count +=1

print(count)

这是我所有版本的禁食版本。我认为 1000x1000 网格大约需要 15 分钟,但现在我有一个更大的网格,它运行了一个小时并且在 5% 左右。如果有人对如何改进代码有任何想法,我会很高兴收到一些反馈。

提前致谢!

【问题讨论】:

    标签: python for-loop optimization


    【解决方案1】:

    如果您使用云软件,我建议您将等式拆分为 16 个不同的程序,这些程序分别运行。如果不是,让较小的方程连续运行。这样一来,您就不需要一次渲染所有内容的大型程序。

    【讨论】:

      【解决方案2】:

      使用 numba,您可以编译 CheckIfObstacle 并使其非常快速且内存高效。就我而言,您可以说我需要 49000x12000 网格。所以使用 numpy 和 numba 对我来说是救命稻草,你可以看到使用 numba 与使用 numpy 的最佳速度的比较。 或者你可以使用 Cython,它与 numba 相比会有点复杂并且并行性很困难

      在函数顶部添加 numba jit 装饰器,包括正确的类型规范。这只是一个示例,不存储计算,但最好将 numba 添加到优化列表中

      @nb.njit((nb.float64[:], nb.float64[:, :]), parallel=True)
      def CheckIfObstacle(point, Obstacle):
      
          for i in nb.prange(Obstacle):
              obs = Obstacle[i]
              # condition for a point being behind a barrier that is on positive side of Grid
              if obs[0]>0 and point[0] >= obs[0] and (obs[1] >= point[1] >= obs[2]):
                  return True
      
              # condition for a point being behind a barrier that is on negative side of Grid
              elif obs[0]<0 and point[0] <=obs[0] and (obs[1]>= point[1]>= obs[2]):
                  return True
      
          return False    
      
      

      我也遇到过类似问题,求性能和实现Why are np.hypot and np.subtract.outer very fast?

      【讨论】:

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