2014-07-24 6 views
4

길이가 다른 두 개의 배열이 있습니다. 하나는 매끈한 다각형을 포함하고, 다른 하나는 매끈한 점을 포함합니다. 두 배열의 모든 가능한 요소 조합에 대해 a_polygon.contains (a_point) 매끄러운 함수를 실행하고 싶습니다.매끄러운 객체 두 개의 numpy 배열에 pairwise shapely 함수 적용

나는 행의 모든 ​​가능한 조합이 바람직한 중간 단계가 될 수있는 두 개의 열 행렬을 구축하면서 this post을보고있었습니다. 그러나 'cartersian (arrays)'함수의 루프는 입력 데이터가 큰 경우 성능을 저해 할 수 있습니다.

나는 배열 중 하나를 방송하기 위해 노력하고 매끈한 기능 적용 :

Polygons_array[:,newaxis].contains(Points_array) 

을하지만, 오프 물론 작동하지 않습니다. 최근 출시 된 geopandas 라이브러리를 알고 있지만 Canopy 설치 옵션이 아닙니다.

+2

은 빠른 그들이 예를 들어'bool' 또는'double'이 아닌 일반 파이썬 같은 기본 유형을 포함 할 때입니다 : 다각형 및 포인트를 매핑하는 것은 그 권리를 증명하는 것 Shapely 패키지의 오브젝트와 같은 오브젝트. –

+0

잘 알고 있습니다. 다른 사람이 좀 더 자세히 설명해 줄 수 있습니까? 그건 그렇고, 아래에 나는 전체 과정을 수행 할 수있는 방법을 게시했다. – Jaqo

답변

3

다음 코드는 길이가 다른 두 개의 배열에 포함 된 기하학적 객체에 함수를 적용하는 방법을 보여줍니다. 이 접근법은 루프 사용을 피합니다. Pandas '가 적용되며 Numpy의 .vectorize 및 방송 옵션이 필요합니다.

우선 몇 수입 다음 두 어레이 고 생각이 다음

import numpy as np 
import pandas as pd 
from shapely.geometry import Polygon, Point 

polygons = [[(1,1),(4,3),(4,1),(1,1)],[(2,4),(2,6),(4,6),(4,4),(2,4)],[(8,1),(5,1),(5,4),(8,1)]] 
points = [(3,5),(7,3),(7,6),(3,2)] 

다각형과 점 형상 물체를 포함하는 배열을 얻을 수있다 :

geo_polygons = pd.DataFrame({'single_column':polygons}).single_column.apply(lambda x: Polygon(x)).values 
geo_points = pd.DataFrame({'single_column':points}).single_column.apply(lambda x: Point(x[0], x[1])).values 
# As you might noticed, the arrays have different length. 

지금 함수가 적용될을 두 배열 모두에 정의되고 벡터화됩니다 :

def contains(a_polygon, a_point): 
    return a_polygon.contains(a_point) 
contains_vectorized = np.vectorize(contains) 

그런 식으로 함수는 벡터의 모든 요소에 적용될 수 있도록 준비됩니다. 다음과 같은 배열을 반환

contains_vectorized(geo_polygons, geo_points[:,np.newaxis]) 

:

array([[False, True, False], 
    [False, False, False], 
    [False, False, False], 
    [ True, False, False]], dtype=bool) 

열이 점에 다각형 및 행에 해당하는 점 배열을 방송하는 것은 페어 평가를 처리합니다. 이 배열의 부울 값은 첫 번째 점이 두 번째 다각형 안에 있음을 보여줍니다. 어느 것이 좋습니다. NumPy와 배열을 사용하여 내 이해

from descartes import PolygonPatch 
import matplotlib.pyplot as plt 
fig = plt.figure(1, figsize = [10,10], dpi = 300) 
ax = fig.add_subplot(111) 
offset_x = lambda xy: (xy[0] + 0.1, xy[1]) 
offset_y = lambda xy: (xy[0], xy[1] - 0.5) 
for i,j in enumerate(geo_polygons): 
    ax.add_patch(PolygonPatch(j, alpha=0.5)) 
    plt.annotate('polygon {}'.format(i + 1), xy= offset_y(tuple(j.centroid.coords[0]))) 
for i,j in enumerate(geo_points): 
    ax.add_patch(PolygonPatch(j.buffer(0.07),fc='orange',ec='black')) 
    plt.annotate('point {}'.format(i + 1), xy= offset_x(tuple(j.coords[0]))) 
ax.set_xlim(0, 9) 
ax.set_ylim(0, 7) 
ax.set_aspect(1) 
plt.show() 

Mapped geometries

+0

대용량 데이터 세트의 경우 공간 인덱스를 사용하는 것이 더 좋을 수도 있다고 덧붙였습니다. 이를 통해 서로 멀리있는 지오메트리 사이의 완전한 교차 테스트를 피함으로써 계산을 절약 할 수 있습니다. 예를 들어, [RTree library] (http://toblerity.org/rtree/)를보십시오. – Jaqo