2013-04-07 32 views
8

Używam Numpy i Python w projekcie, gdzie mapa 2D jest reprezentowany przez ndarray:Jak wyciąć tablicę Numpy do granicy?

map = [[1,2,3,4,5], 
     [2,3,4,2,3], 
     [2,2,2,1,2], 
     [3,2,1,2,3], 
     [4,6,5,7,4]] 
MAP_WIDTH = 5, MAP_HEIGHT = 5 

obiekt ma lokalizację krotka:

actor.location = (3,3) 

i zakres wyświetlania:

actor.range = 2 

Jak napisać funkcję actor.view_map(map), tak aby mapa zwróciła obszar otaczający lokalizację aktora do pewnego zakresu. Na przykład (przy użyciu powyższej mapy)

range = 1 
location = (3, 2) 
=> 
[[2,3,4], 
[3,4,2], 
[2,2,1]] 

ale jeśli zakres aktora przebiega zbyt daleko Chcę mapę wypełnione -1:

range = 1 
location = (1,1) 
[[-1,-1,-1], 
[-1, 1, 2], 
[-1, 2, 3]] 

najprostszy przypadek jest w zakresie od 0, co zwraca bieżący kwadrat:

range = 0 
location = (1, 2) 
[[2]] 

Jak podzielić mapę na określoną granicę?

+1

Ile kosztuje "actor.range"? Jeśli zawsze będzie mniej niż pewna (stosunkowo niewielka) wartość, istnieje łatwa optymalizacja (buforuj strony z -1 i napisz prostą klasę opakowania). –

+0

Zawsze będzie mniej niż połowa szerokości/wysokości mapy - ale jeśli dodaję granicę do mapy na tym poziomie, podwoiłoby to (?) Jej rozmiar ... – sdasdadas

+1

Bliżej poczwórnie (obszar == długość kwadratu), faktycznie . Znacznie przyspiesza to indeksowanie, jeśli możesz sobie pozwolić na wykorzystanie pamięci. –

Odpowiedz

4

Tak więc, dzięki Joe Kingtonowi dodałem obramowanie wokół mojej mapy (wypełnione -1s).

Oto jak to zrobiłem, ale nie może to być bardzo pythonowy odkąd tylko zaczął z języka/Library:

map = numpy.random.randint(10, size=(2 * World.MAP_WIDTH, 2 * World.MAP_HEIGHT)) 
map[0 : World.MAP_WIDTH/4, :] = -1 
map[7 * World.MAP_WIDTH/4 : 2 * World.MAP_WIDTH, :] = -1 
map[:, 0 : World.MAP_HEIGHT/4] = -1 
map[:, 7 * World.MAP_HEIGHT/4 : 2 * World.MAP_WIDTH] = -1 
+3

Możesz dodać ramkę wokół twojej mapy używając funkcji 'np.pad':' np.pad (mapa, 1, tryb = 'stała', stała_wartości = -1) ' – askewchan

+0

Wskazówka: unikaj używania' map' jako zmiennej Nazwa. To jest wbudowana funkcja w Pythonie. https://docs.python.org/3/library/functions.html#map – grisaitis

2

Oto mały klasy Box aby korzystając z pól łatwiejsze -

from __future__ import division 
import numpy as np 

class Box: 
    """ B = Box(2d numpy array A, radius=2) 
     B.box(j, k) is a box A[ jk - 2 : jk + 2 ] clipped to the edges of A 
     @askewchan, use np.pad (new in numpy 1.7): 
      padA = np.pad(A, pad_width, mode="constant", edge=-1) 
      B = Box(padA, radius) 
    """ 

    def __init__(self, A, radius): 
     self.A = np.asanyarray(A) 
     self.radius = radius 

    def box(self, j, k): 
     """ b.box(j, k): square around j, k clipped to the edges of A """ 
     return self.A[ self.box_slice(j, k)] 

    def box_slice(self, j, k): 
     """ square, jk-r : jk+r clipped to A.shape """ 
      # or np.clip ? 
     r = self.radius 
     return np.s_[ max(j - r, 0) : min(j + r + 1, self.A.shape[0]), 
         max(k - r, 0) : min(k + r + 1, self.A.shape[1])] 

#............................................................................... 
if __name__ == "__main__": 
    A = np.arange(5*7).reshape((5,7)) 
    print "A:\n", A 
    B = Box(A, radius=2) 
    print "B.box(0, 0):\n", B.box(0, 0) 
    print "B.box(0, 1):\n", B.box(0, 1) 
    print "B.box(1, 2):\n", B.box(1, 2) 
+0

Nie miałem jeszcze okazji tego wypróbować, ale dziękuję za odpowiedź! – sdasdadas

+0

Podoba mi się to, odbierz ode mnie prezentację :) –

Powiązane problemy