2012-10-12 3 views
10

그리드에 해당하는 점 목록을 만들고 싶습니다. 그래서 (0,0)에서 (1,1)까지의 영역 그리드를 만들고 싶다면 점 (0,0), (0,1), (1,0), (1, 0).Numpy meshgrid points

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

결과를 항복 :

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

내 질문은 두 가지이다 :

나는이 다음 코드를 사용하여 수행 할 수 있다는 것을 알고

  1. 이 더 나은가요 이 일을하는 방법?
  2. 이것을 더 높은 차원으로 일반화 할 수있는 방법이 있습니까?

답변

24

난 그냥 NumPy와의 문서가이 작업을 수행 할 수있는 더 빠른 방법을 제공 것으로 나타났습니다 :

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

이 쉽게 연결 meshgrid2 기능을 사용하여 그 결과 그리드에 '라벨'을 매핑 이상의 차원으로 일반화 될 수 .

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

결과는 각 축 1000 틱이있는 3D 배열의 zip 방법보다 약 35 배 빠릅니다.

출처 : http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.gaussian_kde.html#scipy.stats.gaussian_kde

두 가지 방법이 코드의 다음 섹션을 고려 비교하려면 :

그리드를 만드는 데 도움이 될 것입니다 속담 눈금을 만듭니다.

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) 

meshgrid에 대한 링크 mgilson 기능 정의 :

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) 

그리드와 시간 두 가지 기능을 작성합니다.

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

나는 오류 메시지가 도착 파일에 파일 ""라인 1 ". \ xxx.py"meshgrid2 SLC에서, 라인 (816), [내가] = 렌즈 [ i] TypeError : 'map'객체는 subscriptable이 아닙니다.'file'xxx.py'는 여러분의 함수를 넣는 곳입니다. –

+0

아마도 map이리스트가 아닌 반복자를 반환하는 python3을 사용하고있을 것입니다. 가장 쉬운 방법은'list'에'map'을 래핑하는 것입니다 :'lens = list (map (len, arrs))'. –

+0

Numpy 1.8 이상에서는 'meshgrid2' 함수가 필요하지 않습니다. 표준'meshgrid'가 더 높은 차원을 지원하기 때문입니다. – fhchl

9

격자 점은 항상 필수 요소입니까?

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

불행하게도,이 충족되지 (0부터 시작) 적분 가정 이후 영업 이익의 요구 사항을 충족하지 않는 : 그렇다면, 당신은 numpy.ndindex

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

더 높은 차원을 사용할 수 있습니다 . 다른 사람들이 이러한 가정이 맞는 동일한 것을 찾고있는 경우에만이 답을 남겨 둘 것입니다.


이 작업을 수행하는 또 다른 방법은 zip에 의존 :

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

이 부분은 임의의 크기로 잘 확장 할 수 있습니다. 안타깝게도 np.meshgrid은 여러 차원에 맞게 확장되지 않으므로이 부분을 해결해야하거나 작동한다고 가정하면이 SO answer을 사용하여 고유 한 ndmeshgrid 함수를 만들 수 있습니다.

+0

좋은 제안하지만, 불행히도 그들은하지 않습니다. 편집 ... 또한 범위가 반드시 점 (0,0, ...)으로 시작하지는 않습니다. –

+0

@ 주니퍼 - 너무 나쁨. 내가 관심을 가질만한 또 다른 솔루션을 추가했습니다 ... – mgilson

+0

그럴 겁니다. 감사! '역 추적 (마지막으로 가장 최근 통화) : –

1

은 그러나 그것을 할 수있는 또 다른 방법은 다음과 같습니다 더 높은 차원으로 일반화 될 수

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

, 예컨대 :

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]])