Простое решение для усреднения данных по площади 0,1 м * 0,1 м
Для этого необходимо преобразовать координаты широты и долготы в координаты x, y.
Здесь я использую модуль utm
:
x,y,_,_ = utm.from_latlon(latitude, longitude)
После этого вы можете создать новый столбец, который будет представлять вашу координату x, y в дециметрах:
def apply_fun (raw):
x,y,_,_ = utm.from_latlon(raw['Lat'],raw['Long'])
return str(np.round(x*10))+"|"+str(np.round(y*10))
Затем добавьте его в свой фрейм данных:
x = df.apply(lambda row : apply_fun(row),axis=1)
df.insert(3,'Group',x)
, и вы примените функцию группировки:
gdf = df.groupby(['Group']).agg({"Lat":["mean"],"Long":["mean","count"],"val":["mean"]})
gdf = gdf.reset_index().drop(columns=['Group'],level=0)
gdf.columns = [' '.join(col) for col in gdf.columns]
И все готово! :)
Обобщение предыдущего решения
Чтобы сгруппировать данные по k1 метрам * k2 метра, просто измените эту функцию:
def apply_fun (raw):
x,y,_,_ = utm.from_latlon(raw['Lat'],raw['Long'])
return str(np.round(x/k1))+"|"+str(np.round(y/k2))
Критика предыдущего решения
Как я уже говорил ранее, чтобы решить эту проблему, мы должны преобразовать координаты lat, long в координаты x, y.
В предыдущем решении я преобразовал координаты lat, long в utm. Система utm представляет собой картографическую проекцию c, которая делит Землю на 120 областей: 60 на север и 60 на юг. Поэтому, когда мы делаем:
x,y,area_number,NS = utm.from_latlon(raw['Lat'],raw['Long'])
(x,y)
- наша позиция в области (area_number,NS)
. Мы можем заключить, что наше решение работает тогда и только тогда, когда наши датчики находятся в одной и той же области UTM.
Мы также можем выполнить это преобразование, используя преобразования ECEF, которые непосредственно преобразуют широту, длину в координаты x, y. Я не знаю точности этих методов, и поскольку нас просят о точности с точностью до десятой доли метра, я предпочитаю выбирать преобразование utm, которое выглядит более точным.
Если вы хотите использовать метод ECEF, сделанный так:
import pyproj
def gps_to_ecef_pyproj(lat, lon, alt):
ecef = pyproj.Proj(proj='geocent', ellps='WGS84', datum='WGS84')
lla = pyproj.Proj(proj='latlong', ellps='WGS84', datum='WGS84')
x, y, z = pyproj.transform(lla, ecef, lon, lat, alt, radians=False)
return x, y, z
x,y,z = gps_to_ecef_pyproj(raw['Lat'],raw['Long'],0)
(я беру код отсюда: https://gis.stackexchange.com/questions/230160/converting-wgs84-to-ecef-in-python)