title: Any way to speed up this python code (point in polygon)?
body: <p>I have two files, one with points and its id. Another one with polygons and its id and some more columns. I am trying to get the polygon id associated with each point. I have nearly 1.7 million points and 50000 polygons. And the point in polygon check is running forever in IPython notebook, Is there a way to optimise my code here or may be use multiprocessing module and do parallel process to speed up the point in polygon check?</p>
  
  <p>First reading the polygon file.</p>
  
  <pre><code>import shapefile
  import shapely
  polygons_sf = shapefile.Reader("ploygonshapefile.shp")
  polygon_shapes = polygons_sf.shapes()
  polygon_points = [q.points for q in polygon_shapes]
  from shapely.geometry import Polygon
  polygons = [Polygon(q) for q in polygon_points]
  polygons_sf_records = polygons_sf.records() #To get the polygon id
  </code></pre>
  
  <p>Then creating an rtree index for the polygon</p>
  
  <pre><code>from rtree import index
  idx = index.Index() #creating an rtree
  count = -1
  for a,b in zip(polygon_shapes,polygons_sf_records):
      count +=1
      idx.insert(count,a.bbox,obj=b[1])   
  </code></pre>
  
  <p>Then loading in the point file.</p>
  
  <pre><code>points_sf = shapefile.Reader("pointshapefile.shp")
  point_shapes = points_sf.iterShapes()
  #Creating points as list to iterate
  point_coords= [q.points[0] for q in point_shapes]
  from shapely.geometry import Point
  points = [Point(q.points[0]) for q in point_shapes]
  points_sf_records = points_sf.records() #To get the point id
  </code></pre>
  
  <p>Then trying to find out the polygon id for each point.</p>
  
  <pre><code>matches = []
  for i in range(len(points)): #Iterate through each point
      temp= None
      #Iterate only through the bounding boxes which contain the point
      for j in idx.intersection(point_coords[i]):
      #Verify that point is within the polygon itself not just the bounding box
          if points[i].within(polygons[j]):
              temp=j
              break
              matches.append({'Point_id' : points_sf_recods[i][0],'Polygon_id' : polygons_sf_records[j][1]}) #Either the first match found, or None for no matches
  </code></pre>