#python #pandas #numpy #scipy
#питон #панды #numpy #scipy
Вопрос:
Фрейм grouped
данных имеет следующее описание:
- ПОЛЬЗОВАТЕЛЬ: представляет пользователя;
- ПРЕДПОЛАГАЕМАЯ РЕЗИДЕНТНОСТЬ: антенна, ближайшая к месту жительства пользователя;
- CALL_LOC: антенна, ближайшая к месту, где пользователь совершил вызов.
фрейм данных grouped
:
import pandas as pd
import numpy as np
from math import sin, cos, sqrt, atan2, radians
from scipy.spatial.distance import pdist, squareform
df = pd.DataFrame({'USER':[1,2,3,1,1,2],
'ANTENNA_ID': ['SJDR1', 'LD1', 'LD1', 'LD', 'TR', 'SVM']})
df2 = pd.DataFrame({'USER': [1,2,3,4,5],
'PRESUMED_RESIDENCE': ['SJDR1', 'LD1', 'LD1', 'TR', 'SVM']})
merged = pd.merge(df, df2, left_on='USER', right_on='USER')
grouped = merged.groupby('USER').agg({'PRESUMED_RESIDENCE': min, 'ANTENNA_ID':list}).reset_index()
grouped['ANTENNA_ID'] = [[z for z in x if z!=y]
for x,y in zip(grouped['ANTENNA_ID'],
grouped['PRESUMED_RESIDENCE'])]
grouped = grouped.rename(columns={'ANTENNA_ID': 'CALL_LOC'})
Фрейм antennas_loc
данных содержит пару кординат для каждой антенны:
antennas_loc = pd.DataFrame({'ANTENNA_ID': ['SJDR1', 'LD1', 'LD2', 'TR', 'SVM'],'LAT': [-22.98, -22.97, -22.92, -22.87, -22.89], 'LONG': [-43.19, -43.39, -43.24, -43.28, -43.67]})
antennas_loc
Ниже я использовал dist
функцию для вычисления расстояния между антеннами:
def dist(x, y):
lat1 = radians(x[0])
lon1 = radians(x[1])
lat2 = radians(y[0])
lon2 = radians(y[1])
R = 6373.0
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat/2) ** 2 cos(lat1) * cos(lat2) * sin(dlon/2) ** 2
c = 2 * atan2(sqrt(a), sqrt(1 - a))
distance = R * c
return round(distance, 4)
distances = pdist(antennas_loc[['LAT', 'LONG']].values, metric=dist)
points = antennas_loc['ANTENNA_ID'].values
result = pd.DataFrame(squareform(distances), columns=points, index=points)
result
Что мне нужно сделать сейчас, так это создать столбец в сгруппированном фрейме данных, который представляет расстояние, пройденное пользователем, на основе его PRESUMED_RESIDENCE
. Взяв пользователя 1 в качестве примера, вычисление будет следующим:
PRESUMED_RESIDENCE
: SJDR1CALL_LOC
: [LD2, TR]- Пройденное расстояние: (расстояние между SJDR1 и LD2) (расстояние между SJDR1 и TR).
Строка для пользователя 1 будет выглядеть следующим образом:
USER | PRESUMED_RESIDENCE | CALL_LOC | TRAVELLED_DISTANCE
1 | SJDR1 | [LD2, TR]| 23,7326
Однако я понятия не имею, как я могу просмотреть результат фрейма данных, выполнить поиск координат места жительства и вычислить расстояние от этой точки до мест соединения. Кто-нибудь может помочь?
Ответ №1:
Я предполагаю, что ваш первый фрейм данных на самом деле:
df = pd.DataFrame({'USER':[1,2,3,1,1,2],
'ANTENNA_ID': ['SJDR1', 'LD1', 'LD1', 'LD2', 'TR', 'SVM']})
Тогда это должно сработать:
from math import sin, cos, sqrt, atan2, radians
from scipy.spatial.distance import pdist, squareform
df = pd.DataFrame({'USER': [1,2,3,1,1,2],
'ANTENNA_ID': ['SJDR1', 'LD1', 'LD1', 'LD2', 'TR', 'SVM']})
df2 = pd.DataFrame({'USER': [1,2,3,4,5],
'PRESUMED_RESIDENCE': ['SJDR1', 'LD1', 'LD1', 'TR', 'SVM']})
merged = pd.merge(df, df2, left_on='USER', right_on='USER')
merged = merged[merged['ANTENNA_ID'] != merged['PRESUMED_RESIDENCE']]
antennas_loc = pd.DataFrame({'ANTENNA_ID': ['SJDR1', 'LD1', 'LD2', 'TR', 'SVM'],
'LAT': [-22.98, -22.97, -22.92, -22.87, -22.89],
'LONG': [-43.19, -43.39, -43.24, -43.28, -43.67]})
def dist(x, y):
lat1 = radians(x[0])
lon1 = radians(x[1])
lat2 = radians(y[0])
lon2 = radians(y[1])
R = 6373.0
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat / 2) ** 2 cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2
c = 2 * atan2(sqrt(a), sqrt(1 - a))
distance = R * c
return round(distance, 4)
distances = pdist(antennas_loc[['LAT', 'LONG']].values, metric=dist)
points = antennas_loc['ANTENNA_ID'].values
result = pd.DataFrame(squareform(distances), columns=points, index=points)
melt_df = pd.melt(result.reset_index(), id_vars='index')
melt_df.rename(columns={'index': 'ANTENNA_ID', 'variable': 'PRESUMED_RESIDENCE', 'value': 'DISTANCE'}, inplace=True)
df_main = pd.merge(merged, melt_df, left_on=['ANTENNA_ID', 'PRESUMED_RESIDENCE'], right_on=['ANTENNA_ID', 'PRESUMED_RESIDENCE'])
df_final = df_main.groupby(['USER', 'PRESUMED_RESIDENCE']).agg({'ANTENNA_ID': list, 'DISTANCE': sum}).reset_index()
df_final.rename(columns={'ANTENNA_ID':'CALL_LOC', 'DISTANCE': 'TRAVELLED_DISTANCE'}, inplace=True)
print(df_final)