Просторові геопанди приєднуються надзвичайно повільно


14

Я використовую наведений нижче код, щоб знайти країну (а іноді й штат) для мільйонів GPS-точок. На даний момент код займає близько однієї секунди за точку, що надзвичайно повільно. Форма файлу - 6 Мб.

Я читав, що геопанди використовують rtrees для просторових приєднань, що робить їх неймовірно ефективними, але це, здається, не працює тут. Що я роблю неправильно? Я сподівався на тисячу очок за секунду або близько того.

Файл форми та csv можна завантажити тут (5 МБ): 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
Аарон

Відповіді:


17

додавання аргументу op = 'within' у функції sjoin різко прискорює операцію «точка в полігоні».

Значення за замовчуванням op = 'перетинається', яке, мабуть, також призведе до правильного результату, але в 100-1000 разів повільніше.


Для того, щоб кожен , хто читає це, це не означає , що withinце взагалі - то швидше, відповідь READ nick_g в нижче.
inc42

7

Питання задає питання, як скористатись r-деревом у просторових геопандах, а інший відповідь правильно зазначає, що слід використовувати "в межах", а не "перетинає". Однак ви також можете скористатися просторовим індексом r-дерева в геопандах під час використання intersects/ intersection, як це показано в цьому підручнику з дерева-геопандами :

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

Тут, ймовірно, відбувається те, що в індекс rtree подається лише фрейм даних праворуч: https://github.com/geopandas/geopandas/blob/master/geopandas/tools/sjoin.py#L48-L55 Що для op="intersects"Пробіг означав би, що Полігон подається в індекс, тому для кожної точки відповідний многокутник знаходимо через індекс rtree.

Але для op="within"цього геодетафрейми перевернуті, оскільки операція насправді зворотна contains: https://github.com/geopandas/geopandas/blob/master/geopandas/tools/sjoin.py#L41-L43

Отже, що відбулося при переключенні opз op="intersects"на, op="within"це те, що для кожного багатокутника відповідні точки знаходять через індекс rtree, який у вашому випадку заповнив запит.


1
Ви використовували непостійні URL-адреси, чи можете ви оновити їх до певної редакції?
inc42
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.