Saya menggunakan kode di bawah ini untuk menemukan negara (dan terkadang menyatakan) untuk jutaan titik GPS. Kode saat ini membutuhkan sekitar satu detik per titik, yang sangat lambat. Shapefile adalah 6 MB.
Saya membaca bahwa geopanda menggunakan rtrees untuk gabungan spasial, membuatnya sangat efisien, tetapi ini tampaknya tidak berfungsi di sini. Apa yang saya lakukan salah? Saya berharap untuk seribu poin per detik atau lebih.
Shapefile dan csv dapat diunduh di sini (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
python
spatial-join
geopandas
rtree
Alexis Eggermont
sumber
sumber
Jawaban:
menambahkan argumen op = 'inside' dalam fungsi sjoin mempercepat operasi point-in-polygon secara dramatis.
Nilai default adalah op = 'berpotongan', yang saya kira juga akan mengarah pada hasil yang benar, tetapi 100 hingga 1000 kali lebih lambat.
sumber
within
secara umum entah bagaimana lebih cepat, baca jawaban nick_g di bawah ini.Pertanyaan itu menanyakan bagaimana cara memanfaatkan r-tree dalam gabungan spasial geopanda, dan responden lain dengan benar menunjukkan bahwa Anda harus menggunakan 'di dalam' alih-alih 'berpotongan'. Namun, Anda juga dapat memanfaatkan indeks spasial r-tree di geopandas saat menggunakan
intersects
/intersection
, seperti yang ditunjukkan dalam tutorial r-tree geopandas ini :sumber
Apa yang mungkin terjadi di sini adalah bahwa hanya kerangka data di sebelah kanan dimasukkan ke dalam indeks rtree: https://github.com/geopandas/geopandas/blob/master/geopandas/tools/sjoin.py#L48-L55 Yang mana untuk
op="intersects"
run berarti Poligon dimasukkan ke dalam indeks, jadi untuk setiap titik, poligon yang sesuai ditemukan melalui indeks rtree.Tetapi untuk
op="within"
, geodataframe dibalik karena operasi sebenarnya kebalikan daricontains
: https://github.com/geopandas/geopandas/geobandas/blob/master/geopandas/tools/sjoin.py#L41-L43Jadi apa yang terjadi ketika Anda beralih
op
dariop="intersects"
keop="within"
adalah bahwa untuk setiap poligon, poin yang sesuai ditemukan melalui indeks rtree, yang dalam kasus Anda mempercepat kueri.sumber