геопанда объединяет GeoDataframe с другой геометрией - PullRequest
0 голосов
/ 30 ноября 2018

У меня есть измерения GeoDataframe X. Каждое измерение имеет местоположение, которое не обязательно уникально.У меня есть результат GeoDataframe Y. Каждая точка его геометрии уникальна и разнесена по желанию.X имеет следующую форму:

                 geometry  measurement
timestamp                                                            
126         POINT (x1 y1)     0.558624
1133        POINT (x2 y2)     0.188086
1953        POINT (x3 y3)     1.206570
3147        POINT (x4 y4)     2.327880
4154        POINT (x5 y5)     1.603011

И Y выглядит так:

            geometry  value
id                                                       
0    POINT (x'1 y'1)    NaN
1    POINT (x'2 y'2)    NaN
2    POINT (x'3 y'3)    NaN
3    POINT (x'4 y'4)    NaN
4    POINT (x'5 y'5)    NaN

Я хочу объединить измерения X в Y, например, так: Для каждой точки Yвозьмите среднее значение всех значений X, которые находятся в пределах определенного радиуса.

Итак, вот что я придумал:

Y['value'] = Y.geometry.apply(lambda point: X.loc[X.geometry.distance(point) < radius, 'measurement'].mean())

Геометрия имеет высоты, нодавайте забудем их за этот вопрос.

Этот код работает нормально, но для больших наборов данных выполнение занимает очень много времени из-за задействованных скрытых циклов for.

Как я могу оптимизировать это? scipy.spatial.distance.cdist () похоже, что это может помочь, но у меня пока проблемы с его использованием.

1 Ответ

0 голосов
/ 05 декабря 2018

Для людей, которые ищут ответ, мне удалось добиться этого.

Вот код:

import geopandas as gpd
import pandas as pd
import numpy as np
from scipy.spatial import distance

@property
def x(self):
    return pd.Series(self.geometry.apply(lambda p: p.x), name='x')

@property
def y(self):
    return pd.Series(self.geometry.apply(lambda p: p.y), name='y')

@property
def z(self):
    return pd.Series(self.geometry.apply(lambda p: p.z), name='z')


gpd.GeoDataFrame.x = x
gpd.GeoDataFrame.y = y
gpd.GeoDataFrame.z = z

Y_geometry_tuple = (Y.x, Y.y, Y.z)
X_geometry_tuple = (X.x, X.y, X.z)
dist_matrix = distance.cdist(np.atleast_2d(Y_geometry_tuple).T, np.atleast_2d(X_geometry_tuple).T) < radius
meas_matrix = dist_matrix * np.atleast_2d(X['measurement'])
meas_matrix[meas_matrix == 0] = np.nan
Y['value'] = np.nanmean(meas_matrix, 1)

Скорость вычислений значительно возросла (в 300-400 раз быстрее).

...