【发布时间】:2016-08-10 23:00:52
【问题描述】:
我看过这个post 并想做类似的事情,但不完全相同。
我正在实现一个小生活游戏游戏,并使用numpy arrays 表示游戏的状态。所以我需要检查一个cell有多少个活着的邻居。我已经有了一个函数,可以在给定我想要的窗口大小的坐标、行数和列数的情况下获取 邻居窗口。
所以通常我的窗户是这样的 3x3 大小:
T = True
F = False
[[T,T,T],
[F,T,T],
[F,F,F]] # some random truth values
在这个表示中,True 代表一个细胞是活着的。
现在我编写了一些代码迭代状态的所有单元格,使用双 for 循环计算 True 值等等,但我认为可能有更好的 numpy 解决方案。
我会在幼稚的方法中做什么:
- 遍历状态的所有单元格(不仅是窗口)(我想制定一些代码以在单元格满足标准或其他条件时执行(活着并存活或死亡并活着))
- 获取窗口(包装或不包装)(我已经拥有的功能)
- 检查当前单元格是否处于活动状态(可以在状态的 numpy 数组中查找)
- 如果它是活着的,则从活着的邻居计数 -1 开始,否则从 0 开始
- 计算窗口的所有 True 值 (
np.sum) 并将其添加到活着的邻居计数中(如果单元格本身还活着,则为 -1,因此我只计算邻居而不是单元格本身) - 根据存活邻居的数量是否在特定范围内(可配置),写入另一个(新)状态的数组
True值。 (我会从一个数组开始,我使用以下方法创建:np.full((height, width), False, dtype=bool)) - 继续使用新数组,将旧数组保留在列表中以供历史记录或记录目的
基本上:
if cell meets criteria:
write True at the cell's position in a new array
但是满足条件取决于多行,因为状态的 numpy 数组是二维数组。这就是为什么我认为链接的帖子很接近但不完全是我需要的。
我怎样才能以一种有效的 numpy-y 方式做到这一点,避免不必要的循环?
澄清
我正在寻找在 python 中使用 numpy 和 scipy 实现这一点的最佳方法,它的目标是可读性强并具有良好的性能。
【问题讨论】:
-
编写一个明确但清晰地完成所有迭代的版本。并给我们一个测试用例来使用它。然后我们可以帮助简化它,最有可能从最内层循环开始,您可以在其中执行
sum。 -
您可以使用
scipy.ndimage.filters轻松完成此操作,窗口大小为 3。将 True 视为 1 并将 False 视为 0,generic_filter可能与function=lambda a: 1 if a.sum() - a[4] > 4 else 0一起工作。但是如果没有明确的输入/输出示例,就很难说。