Here is one simple way using standard numpy techniques:
1) Make a map consisting of 3x3 blocks with 80% road
>>> 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) Invert the map and zero-pad it
>>> 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) Cut out shifted versions (up, down, left, right) of the inverse map, use (bitwise) or
to find all neighbors of buildings, use and
to only keep neighbors that are road
>>> 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) Mark the parking spots on the map
>>> 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) Bonus: Prettify
>>> 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