2012-10-12 7 views
10

Chcę utworzyć listę punktów odpowiadającą siatce. Jeśli więc chcę utworzyć siatkę regionu od (0,0) do (1,1), to powinien on zawierać punkty (0,0), (0,1), (1,0), (1, 0).Numpy meshgrid points

Wiem, że można to zrobić za pomocą następującego kodu:

g = np.meshgrid([0,1],[0,1]) 
np.append(g[0].reshape(-1,1),g[1].reshape(-1,1),axis=1) 

uzyskując wynik:

array([[0, 0], 
     [1, 0], 
     [0, 1], 
     [1, 1]]) 

Moje pytanie jest dwojaki:

  1. Czy istnieje lepszy sposób robienia tego?
  2. Czy istnieje sposób uogólnienia tego na wyższe wymiary?

Odpowiedz

24

Właśnie zauważyłem, że dokumentacja w numpy zapewnia jeszcze szybszy sposób, aby to zrobić:

X, Y = np.mgrid[xmin:xmax:100j, ymin:ymax:100j] 
positions = np.vstack([X.ravel(), Y.ravel()]) 

ten można łatwo uogólnić na więcej wymiarów Korzystanie z połączonych funkcji meshgrid2 i mapowanie „Ravela” do powstałej sieci .

g = meshgrid2(x, y, z) 
positions = np.vstack(map(np.ravel, g)) 

Wynik jest około 35 razy szybszy niż metoda zip dla tablicy 3D z 1000 znakami na każdej osi.

Źródło: http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.gaussian_kde.html#scipy.stats.gaussian_kde

porównać dwie metody należy uwzględnić następujące fragmenty kodu:

Tworzenie przysłowiowe znaków podziałki, które pomogą stworzyć siatkę.

In [23]: import numpy as np 

In [34]: from numpy import asarray 

In [35]: x = np.random.rand(100,1) 

In [36]: y = np.random.rand(100,1) 

In [37]: z = np.random.rand(100,1) 

Zdefiniuj funkcję mgilson umieszczonego na meshgrid:

In [38]: def meshgrid2(*arrs): 
    ....:  arrs = tuple(reversed(arrs)) 
    ....:  lens = map(len, arrs) 
    ....:  dim = len(arrs) 
    ....:  sz = 1 
    ....:  for s in lens: 
    ....:  sz *= s 
    ....:  ans = [] 
    ....:  for i, arr in enumerate(arrs): 
    ....:   slc = [1]*dim 
    ....:   slc[i] = lens[i] 
    ....:   arr2 = asarray(arr).reshape(slc) 
    ....:   for j, sz in enumerate(lens): 
    ....:    if j != i: 
    ....:     arr2 = arr2.repeat(sz, axis=j) 
    ....:   ans.append(arr2) 
    ....:  return tuple(ans) 

utworzyć siatkę i czas te dwie funkcje.

In [39]: g = meshgrid2(x, y, z) 

In [40]: %timeit pos = np.vstack(map(np.ravel, g)).T 
100 loops, best of 3: 7.26 ms per loop 

In [41]: %timeit zip(*(x.flat for x in g)) 
1 loops, best of 3: 264 ms per loop 
+0

dostałem komunikat o błędzie: 'Traceback (najnowsza rozmowę ostatni): Plik "", wiersz 1, w Plik " \ xxx.py", linia 816, w meshgrid2 SLC [i] = obiektywu [ i] TypeError: obiekt 'map' nie jest plikiem subscriptable 'plik' xxx.py' jest tam, gdzie umieszczam twoją funkcję. –

+0

Prawdopodobnie używasz python3, gdzie mapa zwraca iterator zamiast listy. Najłatwiej zrobić, aby owinąć 'map' w' list': 'lens = list (map (len, arrs))'. –

+0

Powyżej Numpy 1.8 nie ma potrzeby funkcji 'meshgrid2', ponieważ standardowa' meshgrid' obsługuje wyższe wymiary. – fhchl

9

Czy Twoje punkty są zawsze integralne? Jeśli tak, to można użyć numpy.ndindex

print list(np.ndindex(2,2)) 

wyższych wymiarach:

print list(np.ndindex(2,2,2)) 

Niestety, ten nie spełnia wymagań OP od czasu integralnego założeniu (zaczynając od 0) nie jest spełniony . Zostawię tę odpowiedź tylko na wypadek, gdyby ktoś szukał tego samego, gdzie te założenia są prawdziwe.


Innym sposobem na to opiera się na zip:

g = np.meshgrid([0,1],[0,1]) 
zip(*(x.flat for x in g)) 

Ta część łuski ładnie do dowolnych wymiarach. Niestety, np.meshgrid nie skaluje się dobrze do wielu wymiarów, więc część będzie musiała zostać opracowana, lub (zakładając, że działa), można użyć tego SO answer, aby utworzyć własną funkcję ndmeshgrid.

+0

Dobra sugestia, ale niestety nie są. Edytuj ... również zakresy niekoniecznie zaczynają się od punktu (0,0, ...). –

+0

@juniper - Szkoda. Dodałem kolejne rozwiązanie, które może zainteresować ... – mgilson

+0

To wystarczy. Dzięki! –

1

Jeszcze innym sposobem, aby to zrobić jest:

np.indices((2,2)).T.reshape(-1,2) 

które można uogólnić do wyższych wymiarów, np .:

In [60]: np.indices((2,2,2)).T.reshape(-1,3) 
Out[60]: 
array([[0, 0, 0], 
     [1, 0, 0], 
     [0, 1, 0], 
     [1, 1, 0], 
     [0, 0, 1], 
     [1, 0, 1], 
     [0, 1, 1], 
     [1, 1, 1]])