python - 对 2D numpy 数组进行切片、索引和迭代
问题描述
我在我的大学注册了 Python 初学者课程。我们有一个编程任务,我一直坚持。
我们有一个任务是在地图中找到两点之间的路线,地图是一个 2D numpy 数组。首要任务之一是将由自由道路(1)和建筑物(0)组成的数组转换为一个数组,其中建筑物周围的所有位置(左、右、下、上)都转换为停车位(-1)
我开始编写一个函数来生成正确大小的 2D numpy 数组:
def get_map():
map = np.random.randint(2, size=(12, 10))
return map
现在我想编写另一个以地图为参数的函数,并返回停车位从 1 转换为 -1 的地图。
def adjusted_map(map):
map_adjusted =
return map_adjusted
我主要被困在 0 的上方和下方的元素上。左右我可以这样做,因为这与一维数组或普通列表、字符串等没有什么不同。如果这是一个愚蠢的问题,我很抱歉,但我查看了关于索引、切片和迭代 numpy 数组的 numpy 文档,但我找不到我的问题的解决方案。
解决方案
这是使用标准 numpy 技术的一种简单方法:
1) 制作一张由 3x3 块组成的地图,其中 80% 道路
>>> map_ = np.kron(np.random.random((6, 5)) < 0.8, np.ones((3, 3), int))
>>> map_
array([[1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0]])
2)反转地图并将其补零
>>> helper = np.pad(1-map_, ((1, 1), (1, 1)), 'constant')
>>> helper
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0],
[0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0],
[0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
3) 剪掉逆向地图的移位版本(上、下、左、右),使用(按位)or
查找建筑物的所有邻居,and
用于仅保留道路邻居
>>> parking = map_ & (helper[2:, 1:-1] | helper[:-2, 1:-1] | helper[1:-1, 2:] | helper[1:-1, :-2])
>>> parking
array([[0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1],
[0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0],
[0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0],
[0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0]])
4) 在地图上标记停车位
>>> result = map_ - 2*parking
>>> result
array([[ 1, 1, -1, 0, 0, 0, 0, 0, 0, -1, 1, 1, 1, 1, 1],
[ 1, 1, -1, 0, 0, 0, 0, 0, 0, -1, 1, 1, 1, 1, 1],
[ 1, 1, -1, 0, 0, 0, 0, 0, 0, -1, 1, 1, 1, 1, 1],
[ 1, 1, -1, 0, 0, 0, -1, -1, -1, 1, 1, 1, 1, 1, 1],
[ 1, 1, -1, 0, 0, 0, -1, 1, 1, 1, 1, 1, 1, 1, 1],
[-1, -1, -1, 0, 0, 0, -1, -1, -1, 1, 1, 1, 1, 1, 1],
[ 0, 0, 0, -1, -1, -1, 0, 0, 0, -1, 1, 1, 1, 1, 1],
[ 0, 0, 0, -1, 1, -1, 0, 0, 0, -1, 1, 1, 1, 1, 1],
[ 0, 0, 0, -1, 1, -1, 0, 0, 0, -1, 1, 1, 1, 1, 1],
[ 0, 0, 0, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1],
[ 0, 0, 0, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[ 0, 0, 0, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1],
[-1, -1, -1, 1, 1, -1, 0, 0, 0, -1, 1, 1, 1, 1, 1],
[ 1, 1, 1, 1, 1, -1, 0, 0, 0, -1, 1, 1, 1, 1, 1],
[-1, -1, -1, 1, 1, -1, 0, 0, 0, -1, 1, 1, -1, -1, -1],
[ 0, 0, 0, -1, 1, -1, 0, 0, 0, -1, 1, -1, 0, 0, 0],
[ 0, 0, 0, -1, 1, -1, 0, 0, 0, -1, 1, -1, 0, 0, 0],
[ 0, 0, 0, -1, 1, -1, 0, 0, 0, -1, 1, -1, 0, 0, 0]])
5)奖金:美化
>>> symbols = np.array(('x', '.', 'P'))
>>> rowtype = f'U{map_.shape[1]}'
>>> rowtype
'U15'
>>> print('\n'.join(symbols[map_].view(rowtype).ravel()))
...xxxxxx......
...xxxxxx......
...xxxxxx......
...xxx.........
...xxx.........
...xxx.........
xxx...xxx......
xxx...xxx......
xxx...xxx......
xxx............
xxx............
xxx............
......xxx......
......xxx......
......xxx......
xxx...xxx...xxx
xxx...xxx...xxx
xxx...xxx...xxx
>>> print('\n'.join(symbols[result].view(rowtype).ravel()))
..PxxxxxxP.....
..PxxxxxxP.....
..PxxxxxxP.....
..PxxxPPP......
..PxxxP........
PPPxxxPPP......
xxxPPPxxxP.....
xxxP.PxxxP.....
xxxP.PxxxP.....
xxxP..PPP......
xxxP...........
xxxP..PPP......
PPP..PxxxP.....
.....PxxxP.....
PPP..PxxxP..PPP
xxxP.PxxxP.Pxxx
xxxP.PxxxP.Pxxx
xxxP.PxxxP.Pxxx
推荐阅读
- build - CMAKE_CURRENT_SOURCE_DIR 和 CMAKE_SOURCE_DIR 变量之间的区别?
- python - 复活节换月
- linux - Zynq Linux 内核加载地址
- javascript - Google Charts - 您可以将柱形图中的列与图表的中心对齐吗?
- angular - 在 sidenav 菜单上导入惰性组件
- javascript - jQuery - 如何使用一个具有“$(this)”作为选择器的函数,但 $(this) 在第二个函数中有作用域
- php - WooCommerce 管理员创建订单并在订单支付中添加运费
- excel - 带有第二个显示屏的 Active X 命令按钮
- sql - 在同一个表上进行双左连接以进行转置
- javascript - javascript中两个日期之间的特定日期计数