检查单元格和更改与数据帧中的条件匹配的邻居的最有效方法

Most efficient way to check cells and change neighbors matching a condition in a dataframe

我正在使用 pandas 数据框为 rougelike 风格的游戏地图编辑器存储动态 2D 游戏地图。玩家可以绘制和擦除房间。我需要在这些更衣室周围画墙。

我有这个:

0  1  2  3  4  5  6
0  .  .  .  x  .  .
1  .  .  x  x  .  .
2  .  x  x  x  .  .
3  .  .  .  .  .  .
4  .  .  .  .  .  . 

需要这个:

0  1  2  3  4  5  6
0  .  #  #  x  #  .  
1  #  #  x  x  #  . 
2  #  x  x  x  #  . 
3  #  #  #  #  #  . 
4  .  .  .  .  .  . 

最有效的方法是什么?

到目前为止,我遵循了 here 概述的方法,但这使我在 lambda 前后留下了一些嵌套的 iffor。因为我必须首先检查当前是否挖出了一个单元格。然后在更改匹配单元格之前检查所有八个邻居是否被挖出。这确实需要一个关于帧速率的工具。我不可能是第一个遇到这种事情的人,但一直在寻找解决方案。

我希望通过应用 mask 或类似的二进制比较找到一种方法。尽管如此,我仍然不知道如何有效地进行邻居检查而不会退回到嵌套循环中。

您想要做的是二元膨胀。您可以使用 scipy.ndimage.morphology.binary_dilation:

在底层 numpy 数组上执行此操作
from scipy.ndimage.morphology import binary_dilation
import numpy as np

a = df.eq('x').to_numpy()
# [[False False  True  True  True False]
#  [False  True  True  True  True False]
#  [ True  True  True  True  True False]
#  [False  True  True  True False False]
#  [False False False False False False]]

df = pd.DataFrame(np.where(binary_dilation(a), 'x', df))

输出:

   0  1  2  3  4  5
0  .  .  x  x  x  .
1  .  x  x  x  x  .
2  x  x  x  x  x  .
3  .  x  x  x  .  .
4  .  .  .  .  .  .

现在要获得不同的符号,您可以使用更复杂的掩码 (binary_dilation(a)^a) 和 XOR 运算 (^):

a = df.eq('x').to_numpy()
df = pd.DataFrame(np.where(binary_dilation(a)^a, '#', df))

输出:

   0  1  2  3  4  5
0  .  .  #  x  #  .
1  .  #  x  x  #  .
2  #  x  x  x  #  .
3  .  #  #  #  .  .
4  .  .  .  .  .  .
所有邻居

使用不同的结构元素(这里是 1 的 3x3 矩阵):

from scipy.ndimage.morphology import binary_dilation

a = df.eq('x').to_numpy()
kernel = np.ones((3,3))

df = pd.DataFrame(np.where(binary_dilation(a, kernel)^a, '#', df))

输出:

   0  1  2  3  4  5
0  .  #  #  x  #  .
1  #  #  x  x  #  .
2  #  x  x  x  #  .
3  #  #  #  #  #  .
4  .  .  .  .  .  .
其他内核

您可以轻松调整代码以具有任意邻居组合

示例:左上角

kernel = np.array([[1, 1, 0],
                   [1, 1, 0],
                   [0, 0, 0]])

   0  1  2  3  4  5
0  .  #  #  x  .  .
1  #  #  x  x  .  .
2  #  x  x  x  .  .
3  .  .  .  .  .  .
4  .  .  .  .  .  .