यदि आपके पास बड़े डेटाफ़्रेम हैं, तो मुझे वह मिल गया है scipy
cKDTree स्थानिक सूचकांक .query
विधि निकटतम पड़ोसी खोजों के लिए बहुत तेज़ परिणाम देती है। चूंकि यह एक स्थानिक सूचकांक का उपयोग करता है, इसलिए यह डेटाफ्रेम और फिर सभी दूरी को कम से कम पाते हुए लूपिंग की तुलना में तेज़ी से बढ़ने का आदेश देता है। यह आकार में nearest_points
RTree (जियोपैन्डस के माध्यम से उपलब्ध स्थानिक सूचकांक विधि) के साथ उपयोग करने से भी तेज है क्योंकि cKDTree आपको अपनी खोज को वेक्टर करने की अनुमति देता है जबकि दूसरी विधि नहीं है।
यहां एक सहायक फ़ंक्शन है जो gpd2
प्रत्येक बिंदु से निकटतम पड़ोसी की दूरी और 'नाम' लौटाएगा gpd1
। यह मानता है कि दोनों gdfs में एक 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)
और यदि आप एक LineString के निकटतम बिंदु को ढूंढना चाहते हैं, तो यहां एक पूर्ण कार्य उदाहरण है:
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)