Korzystam z poniższego kodu, aby znaleźć kraj (a czasem stan) dla milionów punktów GPS. Kod zajmuje obecnie około jednej sekundy na punkt, co jest niezwykle powolne. Plik shapefile ma 6 MB.
Czytałem, że geopandy wykorzystują rtree do połączeń przestrzennych, co czyni je niesamowicie wydajnymi, ale wydaje się, że to tutaj nie działa. Co ja robię źle? Miałem nadzieję na tysiąc punktów na sekundę.
Plik shapefile i csv można pobrać tutaj (5 MB): 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
źródło
źródło
Odpowiedzi:
dodanie argumentu op = 'Within' w funkcji sjoin znacznie przyspiesza operację punkt-w-wielokącie.
Wartość domyślna to op = „przecina się”, co, jak sądzę, również doprowadziłoby do poprawnego wyniku, ale jest 100 do 1000 razy wolniejsze.
źródło
within
jest generalnie jakoś szybciej czytać nick_g za odpowiedź poniżej.Pytanie dotyczy sposobu wykorzystania r-drzewa w połączeniach przestrzennych geopandas, a inny respondent prawidłowo wskazuje, że należy używać „wewnątrz” zamiast „przecina się”. Jednak możesz również skorzystać z indeksu przestrzennego r-drzewa w geopandach podczas używania
intersects
/intersection
, jak pokazano w tym samouczku r-drzewa geopandas :źródło
Prawdopodobnie dzieje się tutaj to, że tylko ramka danych po prawej stronie jest wprowadzana do indeksu rtree: https://github.com/geopandas/geopandas/blob/master/geopandas/tools/sjoin.py#L48-L55 Co za
op="intersects"
Uruchomienie oznaczałoby, że wielokąt został wprowadzony do indeksu, więc dla każdego punktu odpowiadający mu wielokąt znajduje się na podstawie indeksu rtree.Ale dla
op="within"
, geodataframes są odwrócone, ponieważ operacja jest odwrotnościącontains
: https://github.com/geopandas/geopandas/blob/master/geopandas/tools/sjoin.py#L41-L43Więc po zmianie
op
zop="intersects"
naop="within"
to, co się wydarzyło , dla każdego wielokąta odpowiednie punkty znajdują się w indeksie rtree, co w twoim przypadku przyspieszyło zapytanie.źródło