geopandas spatial เข้าร่วมช้ามาก


14

ฉันใช้รหัสด้านล่างเพื่อค้นหาประเทศ (และบางครั้งระบุ) สำหรับจุด GPS นับล้าน รหัสในปัจจุบันใช้เวลาประมาณหนึ่งวินาทีต่อจุดซึ่งช้ามากอย่างไม่น่าเชื่อ ไฟล์รูปร่างคือ 6 MB

ฉันอ่านว่า geopandas ใช้ rtrees สำหรับการรวมเชิงพื้นที่ทำให้พวกมันมีประสิทธิภาพอย่างเหลือเชื่อ แต่สิ่งนี้ดูเหมือนจะไม่ทำงานที่นี่ ผมทำอะไรผิดหรือเปล่า? ฉันหวังเป็นพันคะแนนต่อวินาทีหรือมากกว่านั้น

สามารถดาวน์โหลด shapefile และ csv ได้ที่นี่ (5MB): https://www.dropbox.com/s/gdkxtpqupj0sidm/SpatialJoin.zip?dl=0

import pandas as pd
import geopandas as gpd
from geopandas import GeoDataFrame, read_file
from geopandas.tools import sjoin
from shapely.geometry import Point, mapping,shape
import time


#parameters
shapefile="K:/.../Shapefiles/Used/World.shp"
df=pd.read_csv("K:/.../output2.csv",index_col=None,nrows=20)# Limit to 20 rows for testing    

if __name__=="__main__":
    start=time.time()
    df['geometry'] = df.apply(lambda z: Point(z.Longitude, z.Latitude), axis=1)
    PointsGeodataframe = gpd.GeoDataFrame(df)
    PolygonsGeodataframe = gpd.GeoDataFrame.from_file(shapefile)
    PointsGeodataframe.crs = PolygonsGeodataframe.crs
    print time.time()-start
    merged=sjoin(PointsGeodataframe, PolygonsGeodataframe, how='left')
    print time.time()-start
    merged.to_csv("K:/01. Personal/04. Models/10. Location/output.csv",index=None)
    print time.time()-start

ลิงค์ข้อมูลของคุณคือ 404
Aaron

คำตอบ:


17

การเพิ่มอาร์กิวเมนต์ op = 'ภายใน' ในฟังก์ชั่น sjoin จะช่วยเพิ่มความเร็วในการทำงานแบบ point-in-polygon อย่างมาก

ค่าเริ่มต้นคือ op = 'intersects' ซึ่งฉันเดาว่าจะนำไปสู่ผลลัพธ์ที่ถูกต้อง แต่จะช้าลง 100 ถึง 1,000 เท่า


ให้กับทุกคนที่อ่านข้อความนี้นี้ไม่ได้หมายความว่าwithinเป็นโดยทั่วไปอย่างใดได้เร็วขึ้นอ่านคำตอบ nick_g ด้านล่าง
inc42

7

คำถามถามว่าจะใช้ประโยชน์จาก r-tree ใน geopandas spatial joins ได้อย่างไรและผู้ตอบอีกคนชี้ให้เห็นอย่างถูกต้องว่าคุณควรใช้ 'ภายใน' แทน 'intersects' อย่างไรก็ตามคุณยังสามารถใช้ประโยชน์จากดัชนี r-tree spatial ใน geopandas ขณะที่ใช้intersects/ intersectionดังที่แสดงในบทช่วยสอน r-tree geopandasนี้:

spatial_index = gdf.sindex
possible_matches_index = list(spatial_index.intersection(polygon.bounds))
possible_matches = gdf.iloc[possible_matches_index]
precise_matches = possible_matches[possible_matches.intersects(polygon)]

6

สิ่งที่น่าจะเกิดขึ้นที่นี่เป็นที่เดียวที่ dataframe ด้านขวาจะถูกป้อนเข้าดัชนี RTree นี้: https://github.com/geopandas/geopandas/blob/master/geopandas/tools/sjoin.py#L48-L55 ซึ่งสำหรับop="intersects"run หมายถึงรูปหลายเหลี่ยมถูกป้อนเข้าสู่ดัชนีดังนั้นสำหรับทุกจุดรูปหลายเหลี่ยมที่สอดคล้องกันจะพบได้ผ่านดัชนี rtree

แต่สำหรับop="within"geodataframes ถูกพลิกเนื่องจากการดำเนินการเป็นจริงตรงกันข้ามกับcontains: https://github.com/geopandas/geopandas/blob/master/geopandas/tools/sjoin.py#L41-L43

ดังนั้นสิ่งที่เกิดขึ้นเมื่อคุณสลับopจากop="intersects"การop="within"เป็นที่สำหรับทุกรูปหลายเหลี่ยมจุดที่สอดคล้องกันที่พบผ่านดัชนี RTree ซึ่งในกรณีของคุณเร่งแบบสอบถาม


1
คุณใช้ URL ที่ไม่ถาวรคุณสามารถอัปเดตเป็นการแก้ไขที่เฉพาะเจาะจงได้ไหม
inc42
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.