Eu tenho 2 geodataframes:
import geopandas as gpd
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'])
e quero encontrar o nome do ponto mais próximo em gpd2 para cada linha em gpd1:
desired_output =
Name ID geometry Nearest
0 John 1 POINT (1 1) Home
1 Smith 1 POINT (2 2) Shops
2 Soap 1 POINT (0 2) Work
Eu tenho tentado fazer isso funcionar usando uma função lambda:
gpd1['Nearest'] = gpd1.apply(lambda row: min_dist(row.geometry,gpd2)['Place'] , axis=1)
com
def min_dist(point, gpd2):
geoseries = some_function()
return geoseries
Respostas:
Você pode usar diretamente a função Shapely Pontos mais próximos (as geometrias do GeoSeries são geometrias Shapely):
Explicação
fonte
sample_point = gpd2.geometry.unary_union[400] /
sample_point in gpd2.geometry
Isso retorna True.gpd2.geometry == sample_point
Isso sai todo falso.gpd2.geometry.geom_equals(sample_point)
funciona.Se você possui grandes quadros de dados, descobri que
scipy
o.query
método de índice espacial cKDTree retorna resultados muito rápidos para pesquisas de vizinhos mais próximos. Como ele usa um índice espacial, é uma ordem de magnitude mais rápida do que percorrer o quadro de dados e encontrar o mínimo de todas as distâncias. Também é mais rápido do que usar o shapely'snearest_points
com RTree (o método de índice espacial disponível via geopandas) porque o cKDTree permite que você vectorize sua pesquisa, enquanto o outro método não.Aqui está uma função auxiliar que retornará a distância e o 'Nome' do vizinho mais próximo em
gpd2
cada ponto emgpd1
. Assume que ambos os gdfs têm umageometry
coluna (de pontos).E se você deseja encontrar o ponto mais próximo de um LineString, aqui está um exemplo completo de trabalho:
fonte
Descobri isso:
É claro que algumas críticas são bem-vindas. Eu não sou fã de recalcular gpd2 ['Dist'] para cada linha de gpd1 ...
fonte
A resposta de Gene não funcionou para mim. Finalmente, descobri que gpd2.geometry.unary_union resultou em uma geometria que continha apenas cerca de 30.000 do meu total de aproximadamente 150.000 pontos. Para qualquer outra pessoa com o mesmo problema, veja como eu o resolvi:
fonte
Para quem tem erros de indexação com seus próprios dados enquanto usa a excelente resposta do @ JHuw , meu problema é que meus índices não estão alinhados. Redefinir o índice de gdfA e gdfB resolveu meus problemas, talvez isso possa ajudá-lo também @ Shakedk .
fonte