Мне нужна помощь. Моя функция группировать людей на самом деле не работает. Проблема довольно проста:
У меня есть кадр данных со следующими столбцами:
Эти столбцы являются случайными местоположениями людей. Длина фрейма данных кратна 9 (в данном примере это 36. В действительности это намного больше).
Я хочу сгруппировать людей по следующей идее:
Сначала я создаю новый столбец с именем «группа». Люди, которые живут близко друг к другу (в соответствии с координатами), назначаются на определенный c номер группы (1, 2 3, ...). Каждая группа состоит из 3 человек.
Теперь сложная часть: Люди с одинаковыми координатами не могут быть в одной группе !
Вот как я это сделал:
Вот данные:
array_data=([[ 50.56419 , 8.67667 , 2. , 160. ],
[ 50.5643136, 8.6772816, 3. , 89. ],
[ 50.5646274, 8.6763909, 0. , 259. ],
[ 50.5661047, 8.6765931, 1. , 100. ],
[ 50.5663442, 8.6575205, 1. , 117. ],
[ 50.56686 , 8.67598 , 1. , 95. ],
[ 50.56747 , 8.67604 , 2. , 199. ],
[ 50.56762 , 8.6702799, 0. , 148. ],
[ 50.5693473, 8.6640855, -1. , 50. ],
[ 50.5693473, 8.6640855, 0. , 111. ],
[ 50.5705819, 8.6597279, 2. , 183. ],
[ 50.57067 , 8.65694 , 2. , 257. ],
[ 50.57075 , 8.65748 , 1. , 211. ],
[ 50.57075 , 8.65748 , 1. , 292. ],
[ 50.5722461, 8.6598248, 2. , 142. ],
[ 50.57254 , 8.65895 , 1. , 116. ],
[ 50.57259 , 8.6592 , 2. , 228. ],
[ 50.5731636, 8.667609 , 1. , 181. ],
[ 50.5737814, 8.6720067, 0. , 173. ],
[ 50.5740356, 8.6718179, 1. , 5. ],
[ 50.5746321, 8.6831284, 3. , 202. ],
[ 50.5747453, 8.6765588, 4. , 119. ],
[ 50.5748992, 8.6611471, 2. , 260. ],
[ 50.5748992, 8.6611471, 3. , 102. ],
[ 50.575 , 8.65985 , 2. , 267. ],
[ 50.5751 , 8.66027 , 2. , 7. ],
[ 50.5751 , 8.66027 , 2. , 56. ],
[ 50.57536 , 8.67741 , 1. , 194. ],
[ 50.57536 , 8.67741 , 1. , 282. ],
[ 50.5755255, 8.6884584, 0. , 276. ],
[ 50.5755273, 8.674282 , 3. , 167. ],
[ 50.57553 , 8.6826 , 2. , 273. ],
[ 50.5755973, 8.6847492, 0. , 168. ],
[ 50.5756757, 8.6846139, 4. , 255. ],
[ 50.57572 , 8.65965 , 0. , 66. ],
[ 50.57591 , 8.68175 , 1. , 187. ]])
Преобразование массива в фрейм данных и переименование столбцов:
df = pd.DataFrame(data=array_data) # convert back to dataframe
df.rename(columns={0: 'latitude', 1: 'longitude', 2:'floor', 3:'id'}, inplace=True) # rename columns
Теперь у нас есть фрейм данных. С помощью следующих функций я пытался сгруппировать людей:
Сначала нам нужно найти способ, чтобы определить расстояния до людей:
def calculate_distance(lat1, lon1, lat2, lon2):
"""
Calculate the shortest distance between two points given by the latitude and
longitude.
"""
earth_radius = 6373 # Approximate / in km.
lat1 = radians(lat1)
lon1 = radians(lon1)
lat2 = radians(lat2)
lon2 = radians(lon2)
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))
return earth_radius * c # in km.
И вот основная функция. Я пытаюсь группировать людей, если они НЕ находятся в одном и том же месте:
def sort_people(all_persons, max_distance_parameter):
'''
People in the same group have different location!
'''
assert len(all_persons) % 9 == 0
all_persons.set_index("id", drop=False, inplace=True)
all_persons["host"] = np.nan
all_persons["group"] = np.nan
scattering_factor= 0.0001 # to seperate same floor numbers
max_distance = max_distance_parameter
group_number = 0
group = []
for _, candidate in all_persons.iterrows():
if len(group) == 3:
for person in group:
all_persons.at[person["id"], "group"] = group_number
group_number += 1
group = []
if len(group) == 0:
group.append(candidate)
else:
for person in group:
distance = calculate_distance(
candidate["latitude"],
candidate["longitude"],
person["latitude"],
person["longitude"],
)
distance = distance
if candidate['floor'] == -1: # consider the floor when calculating the distance
distance = distance + scattering_factor + 0.001
elif candidate['floor'] == 0:
distance = distance + scattering_factor + 0.002
elif candidate['floor'] == 1:
distance = distance + scattering_factor + 0.003
elif candidate['floor'] == 2:
distance = distance + scattering_factor + 0.004
elif candidate['floor'] == 3:
distance = distance + scattering_factor + 0.005
elif candidate['floor'] == 4:
distance = distance + scattering_factor + 0.006
elif candidate['floor'] == 5:
distance = distance + scattering_factor + 0.007
elif candidate['floor'] == 6:
distance = distance + scattering_factor + 0.008
elif candidate['floor'] == 7:
distance = distance + scattering_factor + 0.009
elif candidate['floor'] == 8:
distance = distance + scattering_factor + 0.010
elif candidate['floor'] == 9:
distance = distance + scattering_factor + 0.011
elif candidate['floor'] == 10:
distance = distance + scattering_factor + 0.012
elif candidate['floor'] == 11:
distance = distance + scattering_factor + 0.013
elif candidate['floor'] == 12:
distance = distance + scattering_factor + 0.014
elif candidate['floor'] == 13:
distance = distance + scattering_factor + 0.015
elif candidate['floor'] == 14:
distance = distance + scattering_factor + 0.016
else:
distance = distance + scattering_factor + 0.017
if 0 < distance <= max_distance:
group.append(candidate)
break
Короче говоря: это действительно не работает. В конце я получаю фрейм данных и нахожу людей в тех же местах, которые назначены в ту же группу. Как бы вы это сделали?