【问题标题】:Looping and indexing over large arrays in Python在 Python 中对大型数组进行循环和索引
【发布时间】:2016-02-15 06:17:02
【问题描述】:

我试图在 700x700 的 python numpy 数组中找到索引,以便在单独的数组中找到具有相同索引的数字。我循环了很多次,所以它需要很长时间,我想知道是否有更快的方法来做到这一点。到目前为止,这就是我所拥有的:

我的lat_endlon_end 是我在temp_mask 数组中找到的索引。

掩码在我的 700x700 阵列上创建一个占用空间,其环形大小定义了我希望占用空间有多大。 mask_index 正在查找 temp_mask 等于 1 的位置,因此我可以通过执行以下操作找到单独数组的索引:other_array[footprint_index]。然后,这将为我提供 temp_mask 足迹中的 other_array 的值。

def foot_mask(lat_end,lon_end):
    mask = footprint.footprint(ring_size,ring_size,700,700, 0)
    temp_mask = np.roll(np.roll(mask,lat_end,axis = 0),lon_end, axis = 1)
    mask_index = np.where(temp_mask == 1)
    return mask_index

谢谢!

【问题讨论】:

  • 如果每次迭代的mask 都相同,我想关键是在循环之外进行尽可能多的计算。除此之外,代码看起来相当高效。只要footprint.footprint 不是主要的时间消费者。
  • 如何在函数内部放置一个 for 循环,以便在每次迭代循环时返回 mask_index?我会让它在循环中迭代 7 次以更改“环大小”
  • 您是否也在另一个循环中更改(例如)lat_endlon_end?因为对于这段代码来说,7 次迭代并不是那么多。您能否编辑问题以包括您打算如何调用此函数?如果您还没有实现任何循环,那么伪代码或纯英语也会有所帮助。
  • 我在这个循环上迭代了大约 150,000 次。在我的数据中,将有大约 4000 个 lat_end 和 lon_end 点对应于不同的纬度和经度点。然后对于这些点中的每一个,对于我正在使用的不同时间戳,我将对其进行大约 7 次迭代。
  • 您能否更详细地解释您要解决的问题?理想情况下,发布您自己的缓慢但工作的代码,并展示如何生成一些虚假的输入数据,以便我们可以看到输入和期望的输出是什么。我怀疑可能存在比在循环内调用foot_mask 更快的矢量化方法,但我没有足够的信息继续下去。

标签: python arrays numpy processing-efficiency


【解决方案1】:

因为您希望多次迭代调用此函数,并且它已经使用了高效的 Numpy 函数,所以我认为关键是将尽可能多的代码移到可能存在的任何循环之外。这确实意味着当前函数foot_mask 不能按原样使用,但应该稍微重构一下。

我并不完全清楚你打算如何在循环中调用你的函数,但基本上我建议编写如下代码:

for ring_size in ring_sizes:
    mask = footprint.footprint(ring_size,ring_size,700,700, 0)
    I, J = np.where(mask == 1)

    for lat_end, lon_end in data:  # Or some other loop(s)
        mask_index = ((I + lat_end) % 700, (J + lon_end) % 700)
        # Then use `mask_index` as desired

这样可以减少对footprint.footprintnumpy.where 的调用,并且代码应该运行得更快。对numpy.roll 的调用也已被索引的模数所取代。

但是,如果没有更多信息,很难说如何准确地组织循环以及加速有多大。

【讨论】:

  • 效果很好!我的代码从 45 分钟内运行到 5 分钟!非常感谢,这将节省数月的处理时间!
  • 当我这样做时,它似乎在 mask_index 数组中排序。有没有办法不订购?
  • @Kate - 我需要更多的上下文;)。你的意思是随机顺序还是..?也许您可以编辑您的问题以包含更多详细信息,例如总体目标、外部循环和footprint.footprint 的代码。以及结果顺序的意义。
猜你喜欢
  • 2021-01-30
  • 2018-04-23
  • 2020-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多