首页 > 解决方案 > 对 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 文档,但我找不到我的问题的解决方案。

标签: pythonarraysnumpy

解决方案


这是使用标准 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

推荐阅读