#python #pandas #dataframe
#python #pandas #фрейм данных
Вопрос:
У меня есть следующий фрейм данных:
id x_coordinate y_coordinate money time (hr)
0 545 0.676576 3.079094 4200 1.414706
1 4138 0.262979 -0.769170 700 0.943230
2 5281 -0.301234 -3.568590 200 1.314108
3 4369 -0.585544 1.610388 11600 0.703957
4 2173 -1.239105 3.168139 29200 0.666473
5 9971 -1.556373 -1.624628 18700 0.776165
6 2622 -1.747544 3.145381 100 0.842138
7 4522 -1.923251 -2.695298 36700 0.186741
8 7299 -2.697775 2.038365 500 0.469136
9 5425 -4.443474 0.428256 1400 0.760269
Скажем, отправной точкой является первая строка. Я хочу манипулировать фреймом данных так, чтобы вторая строка была строкой, координаты которой наиболее близки к первой строке, а третья строка — это строка, координаты которой наиболее близки к координатам второй строки из оставшихся строк и так далее.
Представьте координаты на графике, и я начинаю с (0,0), например. Я пытаюсь найти наиболее эффективный способ «перемещения» между этими координатами и в конечном итоге получить (0,0), например, выводом может быть список координат, отсортированных по наиболее эффективному маршруту. Или новый фрейм данных — просто пытаюсь найти способ решить эту проблему
До сих пор я пытался отсортировать df следующим образом:
df = df.sort_values(["x_coordinate", "y_coordinate"], ascending = (False, True))
В качестве альтернативы я также пытался преобразовать столбцы df в списки, используя df.to_list()
и затем сортируя их.
Однако ни один из подходов не дает желаемого результата. Итак, есть какие-нибудь советы о том, как управлять фреймом данных, подобным этому?
Любая помощь очень ценится!
Комментарии:
1. Вы не можете просто отсортировать 2D-вектор по его координатам, чтобы найти, какой из них ближе друг к другу. Вы должны использовать евклидово расстояние между перекрестным произведением каждой точки, а затем решить, как сортировать массив.
2. Один из способов сделать это — выбрать одну из своих координат (возможно, ту, у которой наименьшее значение x), а затем отсортировать остальные на основе евклидова расстояния от этой точки. Это то, что вы ищете?
3. Представьте координаты на графике, и я начинаю с (0,0), например. Я пытаюсь найти наиболее эффективный способ «перемещения» между этими координатами и в конечном итоге получить (0,0)
4. В этом случае я попрошу вас изменить вопрос на say
I am trying to find the most efficient way to 'travel' between these coordinates and end up at (0,0)
. Сортировка фрейма данных — это не то, как вы решаете эту проблему. Это проблема алгебры. Пожалуйста, убедитесь, что вы отразили это в вопросе, поскольку вопрос сейчас очень вводит в заблуждение … чтобы люди могли правильно вам помочь, и вопрос не был закрыт.5. Спасибо за ваше предложение, я изменил название
Ответ №1:
Я думаю, сортировка не поможет. Вам нужно будет взять евклидово расстояние от этих точек от ваших координат, а затем отсортировать по нему. Это даст вам самые близкие точки.
Это то, что я быстро попробовал. Посмотрите, работает ли это. У меня не было возможности проверить результаты.
import numpy as np
import pandas as pd
from scipy import spatial
df = pd.DataFrame({
'id': [545,4138,5281,4369,2173,9971,2622,4522,7299,5425],
'x_coordinate': [0.676576, 0.262979, -0.301234, -0.585544, -1.239105,-1.556373,-1.747544,-1.923251,-2.697775,-4.443474],
'y_coordinate': [3.079094, -0.769170, -3.568590, 1.610388, 3.168139, -1.624628,3.145381,-2.695298,2.038365,0.428256],
})
print(df)
id x_coordinate y_coordinate
0 545 0.676576 3.079094
1 4138 0.262979 -0.769170
2 5281 -0.301234 -3.568590
3 4369 -0.585544 1.610388
4 2173 -1.239105 3.168139
5 9971 -1.556373 -1.624628
6 2622 -1.747544 3.145381
7 4522 -1.923251 -2.695298
8 7299 -2.697775 2.038365
9 5425 -4.443474 0.428256
def shortest_neighbour(pt,nebr):
tree = spatial.KDTree(nebr)
dist = tree.query(pt,2)
return dist[0][1],dist[1][1]
arr=df[['x_coordinate','y_coordinate']].to_numpy().reshape(len(df),2)
df[['Dist','Ord']]=pd.DataFrame(df.apply(lambda row : shortest_neighbour(arr[row.name],arr),axis = 1).tolist(),index=df.index)
print(df)
id x_coordinate y_coordinate Dist Ord
0 545 0.676576 3.079094 1.917749 4
1 4138 0.262979 -0.769170 2.010435 5
2 5281 -0.301234 -3.568590 1.842167 7
3 4369 -0.585544 1.610388 1.689299 4
4 2173 -1.239105 3.168139 0.508948 6
5 9971 -1.556373 -1.624628 1.131783 7
6 2622 -1.747544 3.145381 0.508948 4
7 4522 -1.923251 -2.695298 1.131783 5
8 7299 -2.697775 2.038365 1.458912 6
9 5425 -4.443474 0.428256 2.374851 8
dfs=df.sort_values(by=['Ord','Dist'],ascending =[True,True])
print(dfs)
id x_coordinate y_coordinate Dist Ord
6 2622 -1.747544 3.145381 0.508948 4
3 4369 -0.585544 1.610388 1.689299 4
0 545 0.676576 3.079094 1.917749 4
7 4522 -1.923251 -2.695298 1.131783 5
1 4138 0.262979 -0.769170 2.010435 5
4 2173 -1.239105 3.168139 0.508948 6
8 7299 -2.697775 2.038365 1.458912 6
5 9971 -1.556373 -1.624628 1.131783 7
2 5281 -0.301234 -3.568590 1.842167 7
9 5425 -4.443474 0.428256 2.374851 8
И еще одна вещь, которую я устал. Это расстояние от (0,0). Смотрите Ниже, если это то, что вы хотите.
df['Dist']=df.apply(lambda row: np.linalg.norm(np.zeros(2)-np.array([row.x_coordinate,row.y_coordinate])),axis = 1)
print(df.sort_values(by=['Dist'],ascending =[True]))
id x_coordinate y_coordinate Dist
1 4138 0.262979 -0.769170 0.812884
3 4369 -0.585544 1.610388 1.713538
5 9971 -1.556373 -1.624628 2.249825
0 545 0.676576 3.079094 3.152551
7 4522 -1.923251 -2.695298 3.311122
8 7299 -2.697775 2.038365 3.381260
4 2173 -1.239105 3.168139 3.401836
2 5281 -0.301234 -3.568590 3.581281
6 2622 -1.747544 3.145381 3.598240
9 5425 -4.443474 0.428256 4.464064
Комментарии:
1. Я действительно рассматривал этот подход, но не заканчивается ли это просто сортировкой df по тому, насколько далеко он находится от (0,0)? В этом случае две координаты могут находиться на одинаковом расстоянии от 0, но далеко друг от друга, тогда как я ищу координаты ближайшей строки из координат текущей строки
2. Я отредактировал свой ответ… посмотрите, есть ли от этого какая-либо польза.
3. Спасибо за ваш ответ! Использование K ближайших соседей — это определенно то, что я могу использовать. Мой фактический df намного больше, поэтому теперь я попытаюсь применить его к этому, поскольку я пытаюсь найти оптимизированный маршрут с наибольшим соотношением денег в час в течение срока
4. Я также попытался использовать
scipy.pdist
иscipy.squareform
для вычисления расстояний между всеми парами местоположений и привести его к новому df, который показывает расстояние между заданной точкой и любой другой точкой в фрейме данных