আপনার কাছে যদি বড় ডেটাফ্রেম থাকে তবে আমি খুঁজে পেয়েছি যে scipy
এর সিকেডিট্রি স্পেসিয়াল ইনডেক্স .query
পদ্ধতিটি নিকটতম প্রতিবেশী অনুসন্ধানগুলির জন্য খুব দ্রুত ফলাফল দেয়। এটি একটি স্থানিক সূচক ব্যবহার করে যেহেতু ডেটাফ্রেম এবং তারপরে সমস্ত দূরত্বের সর্বনিম্ন সন্ধানের চেয়ে লুপিংয়ের চেয়ে দ্রুততার উচ্চতার অর্ডারগুলি। এটি nearest_points
আরটিরির সাথে শেপলি ব্যবহারের চেয়েও দ্রুত (জিওপ্যান্ডাসের মাধ্যমে উপলভ্য স্থানিক সূচক পদ্ধতি) কারণ সি কেডিটি্রি আপনাকে আপনার সন্ধানকে ভেক্টরাইজ করার অনুমতি দেয় যেখানে অন্য পদ্ধতি না করে।
এখানে একটি সহায়ক ফাংশন যা gpd2
প্রতি বিন্দু থেকে নিকটতম প্রতিবেশীর দূরত্ব এবং 'নাম' ফিরিয়ে দেবে gpd1
। এটি ধরে নিয়েছে যে উভয় জিডিএফ-এর একটি geometry
কলাম রয়েছে (পয়েন্টগুলির)।
import geopandas as gpd
import numpy as np
import pandas as pd
from scipy.spatial import cKDTree
from shapely.geometry import Point
gpd1 = gpd.GeoDataFrame([['John', 1, Point(1, 1)], ['Smith', 1, Point(2, 2)],
['Soap', 1, Point(0, 2)]],
columns=['Name', 'ID', 'geometry'])
gpd2 = gpd.GeoDataFrame([['Work', Point(0, 1.1)], ['Shops', Point(2.5, 2)],
['Home', Point(1, 1.1)]],
columns=['Place', 'geometry'])
def ckdnearest(gdA, gdB):
nA = np.array(list(zip(gdA.geometry.x, gdA.geometry.y)) )
nB = np.array(list(zip(gdB.geometry.x, gdB.geometry.y)) )
btree = cKDTree(nB)
dist, idx = btree.query(nA, k=1)
gdf = pd.concat(
[gdA, gdB.loc[idx, gdB.columns != 'geometry'].reset_index(),
pd.Series(dist, name='dist')], axis=1)
return gdf
ckdnearest(gpd1, gpd2)
এবং যদি আপনি একটি লাইনস্ট্রিংয়ের নিকটতম বিন্দুটি সন্ধান করতে চান তবে এখানে একটি পূর্ণ কাজের উদাহরণ রয়েছে:
import itertools
from operator import itemgetter
import geopandas as gpd
import numpy as np
import pandas as pd
from scipy.spatial import cKDTree
from shapely.geometry import Point, LineString
gpd1 = gpd.GeoDataFrame([['John', 1, Point(1, 1)],
['Smith', 1, Point(2, 2)],
['Soap', 1, Point(0, 2)]],
columns=['Name', 'ID', 'geometry'])
gpd2 = gpd.GeoDataFrame([['Work', LineString([Point(100, 0), Point(100, 1)])],
['Shops', LineString([Point(101, 0), Point(101, 1), Point(102, 3)])],
['Home', LineString([Point(101, 0), Point(102, 1)])]],
columns=['Place', 'geometry'])
def ckdnearest(gdfA, gdfB, gdfB_cols=['Place']):
A = np.concatenate(
[np.array(geom.coords) for geom in gdfA.geometry.to_list()])
B = [np.array(geom.coords) for geom in gdfB.geometry.to_list()]
B_ix = tuple(itertools.chain.from_iterable(
[itertools.repeat(i, x) for i, x in enumerate(list(map(len, B)))]))
B = np.concatenate(B)
ckd_tree = cKDTree(B)
dist, idx = ckd_tree.query(A, k=1)
idx = itemgetter(*idx)(B_ix)
gdf = pd.concat(
[gdfA, gdfB.loc[idx, gdfB_cols].reset_index(drop=True),
pd.Series(dist, name='dist')], axis=1)
return gdf
c = ckdnearest(gpd1, gpd2)