【问题标题】:Avoid for-loops in assignment of data values在分配数据值时避免 for 循环
【发布时间】:2013-03-06 20:22:21
【问题描述】:

所以这是我之前的问题的一个小后续问题:Generate coordinates inside Polygon 和我的回答 https://stackoverflow.com/a/15243767/1740928 事实上,我想将多边形数据合并到规则网格中。因此,我计算了多边形内的几个坐标,并将它们的纬度/经度组合转换为它们各自的网格列/行组合。

目前,行/列信息存储在一个numpy数组中,其行数对应于数据多边形的数量,其列数对应于多边形中的坐标。

整个代码不到一秒钟,但这段代码是目前的瓶颈(大约 7 秒):

for ii in np.arange(len(data)):
    for cc in np.arange(data_lats.shape[1]):
        final_grid[        row[ii,cc], col[ii,cc] ] += data[ii]
        final_grid_counts[ row[ii,cc], col[ii,cc] ] += 1

数组“data”只包含每个多边形的数据值 (80000,)。数组“row”和“col”包含多边形中坐标的行号和列号(形状:(80000,16))。 如您所见,我正在汇总每个网格单元格中的所有数据值并计算匹配数。因此,我知道每个网格单元的平均值,以防不同的多边形相交。 不过,这两个 for 循环怎么会花费大约 7 秒呢?你能想出更快的方法吗?

【问题讨论】:

  • 这个更适合codereview.stackexchange.com。

标签: python numpy


【解决方案1】:

我认为 numpy 应该添加一个 nd-bincount 函数,我有一个来自我前段时间正在做的一个项目。

import numpy as np

def two_d_bincount(row, col, weights=None, shape=None):
    if shape is None:
        shape = (row.max() + 1, col.max() + 1)
    row = np.asarray(row, 'int')
    col = np.asarray(col, 'int')

    x = np.ravel_multi_index([row, col], shape)
    out = np.bincount(x, weights, minlength=np.prod(shape))
    return out.reshape(shape)

weights = np.column_stack([data] * row.shape[1])
final_grid = two_d_bincount(row.ravel(), col.ravel(), weights.ravel())
final_grid_counts = two_d_bincount(row.ravel(), col.ravel())

我希望这会有所帮助。

【讨论】:

  • +1 没有想到bincount 的方法,但它很有意义。 histogram2d 不能用来做同样的事情吗?
  • 是的,直方图 2d 可能更适合这个问题。
  • 也感谢您的这篇文章!我确实可以用它来加速它!
  • 不得不说纯 histogram2d 和 two_d_bincount 其实比我之前的代码慢了一点。
【解决方案2】:

我可能不完全理解您不同网格的形状,但您可以使用以下方法消除cc 循环:

final_grid = np.empty((nrows,ncols))
for ii in xrange(len(data)):
    final_grid[row[ii,:],col[ii,:]] = data[ii]

这当然假设final_grid 没有其他信息开始(您递增的计数从零开始)。而且我不确定如何测试它是否有效,不了解您的 rowcol 数组是如何工作的。

【讨论】:

  • 感谢您的建议!这个小技巧将运行时间缩短到 4.5 秒!
  • 如果你想得更久一点,你可能也可以避免循环通过ii,但我不确定如何。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-15
  • 2021-09-21
  • 2023-03-27
  • 2012-06-25
  • 2020-03-10
相关资源
最近更新 更多