Попытка найти наиболее эффективный способ «перемещения» из координат, где координаты находятся в фрейме данных pandas

#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, который показывает расстояние между заданной точкой и любой другой точкой в фрейме данных