python - 在网格中标记相邻单元面
问题描述
我有一个熊猫数据框中的节点列表,如下所示:
row col
...
36 182 240
35 182 241
34 182 242
33 182 243
58 183 220
32 183 244
31 183 245
30 183 246
29 183 247
...
该节点的网格如下所示:
我的代码标记了 X-ed 单元格的每个面,因此如果它连接到调整 X-ed 单元格,则标记为 0,如果未连接(打开),则标记为 1。代码无法正常工作沿着一些边缘:
df["Front Face"] = 1
df["Back Face"] = 1
df["Right Face"] = 1
df["Left Face"] = 1
df = df.sort_values(by=['row','col'], ascending=True)
df = df.reset_index(drop=True)
for ix1 in df.index:
try:
if df["col"][ix1] == df["col"][ix1 + 1] - 1:
df["Right Face"][ix1] = 0
df["Left Face"][ix1 + 1] = 0
if df["col"][ix1] == df["col"][ix1 - 1] + 1:
df["Left Face"][ix1] = 0
df["Right Face"][ix1 - 1] = 0
except:
pass
df= df.sort_values(by=['col','row'], ascending=True)
df= df.reset_index(drop=True)
for ix2 in df.index:
try:
if df["row"][ix2] == df["row"][ix2 + 1] - 1:
df["Back Face"][ix2] = 0
df["Front Face"][ix2 + 1] = 0
if df["row"][ix2] == df["row"][ix2 - 1] + 1:
df["Front Face"][ix2] = 0
df["Back Face"][ix2 - 1] = 0
except:
pass
这是单元格 182,243 和 183,244 缺少一个标签的输出的一部分:
row col Front Face Back Face Right Face Left Face
36 182 240 1 1 0 0
35 182 241 1 1 0 0
34 182 242 1 1 0 0
33 182 243 1 0 1 0
58 183 220 1 0 1 1
32 183 244 0 1 0 1
31 183 245 1 1 0 0
30 183 246 1 1 0 0
29 183 247 1 1 0 0
我在这里圈出了图中有问题的单元格:
解决方案
我假设您标记中的每一行都df
占据了一个位置,并且您希望将相邻的单元格标记为前、后、左或右。
如果是这样,您可以以矢量化的方式执行此操作,但我必须承认:我在让索引和 numpy 广播正常工作方面付出了很多努力。
# A random 5 * 10 matrix with 10% of rows marked as "occupied"
n, m = 5, 10
count = int(n * m * 0.1)
df = pd.DataFrame({
'row': np.random.randint(n, size=count),
'col': np.random.randint(m, size=count)
}).drop_duplicates()
让我们构建result
数据框:
from itertools import product
# Every row in `df` marks an occupied position
result = df.set_index(['row', 'col']).assign(Occupied = True)
# Now expand `result` into the full matrix
idx = product(range(n), range(m))
result = result.reindex(idx, fill_value=False)
# Every cell is Open initially
for col in ['Front Face', 'Back Face', 'Right Face', 'Left Face']:
result[col] = 1
# Now start to build out a list of blocked cells
occupied = result.query('Occupied').index.to_frame().to_numpy()
valid_index = result.index
faces = {
'Front Face': [-1, 0],
'Back Face': [1, 0],
'Left Face': [0, -1],
'Right Face': [0, 1]
}
for face, offset in faces.items():
blocked = valid_index.intersection([tuple(i) for i in occupied + offset])
result.loc[blocked, face] = 0
为了说明结果,让我们构建一个辅助函数:
from IPython.display import display
def illustrate(result):
display_df = result['Occupied'].map({True: 'x', False: ''}).reset_index()
display_df = display_df.pivot(index='row', columns='col', values='Occupied')
is_open = result[['Front Face', 'Back Face', 'Right Face', 'Left Face']].all(axis=1)
style_df = (
is_open.map({
True: 'background-color: white',
False: 'background-color: rgba(255,0,0,0.2)'
})
.unstack()
)
display(display_df.style.apply(lambda _: style_df, axis=None))
illustrate(result)
结果(红色的单元格在任何面上都有一个 0):
推荐阅读
- java - 动态检查实例是否实现接口
- c++ - 与基本面斗争。尤其是 char[]、char* 和从数组中读取。也许我应该使用类型字符串
- regex - 用于在每个 if 语句中复制条件的正则表达式
- java - 共享首选项不会用相同的键覆盖?
- python-3.x - 创建一个接受参数的矩形类
- javascript - jQuery fadeToggle 上下跳动
- c++ - 默认参数的 C++ 重新定义:参数 1 (Vector2D)
- .net-core - SignalR Core Hub 与 BackgroundService .NET Core 交互
- mysql - 具有多对一关系的插入异常
- python-3.x - 将 matplotlib 直方图附加到列表中,而不覆盖