import numpy as np
import pandas as pd
Это данные для расчета расстояний
data = pd.read_csv(r'survey_data.csv',
delimiter=',')
start = pd.read_csv(r'start_points.csv',
delimiter=',')
print(data)
print(start)
data['Trans'] = data['Trans'].str.upper()
получить только трансекты, используемые из файла начальных точек
unique = data['Trans'].unique()
start = pd.DataFrame(start.loc[start['Trans'].isin(unique)])
выбрать столбцы, которые будут использоваться
start['Dist'] = 0.0
cols = ['Y','X', 'Elev']
Установите Trans в качестве индексной колонки
a = data.set_index('Trans')[cols]
b = start.set_index('Trans')[cols]
используйте теорему Пифагора для расстояния. В этом фрагменте кода я получаю сообщение об ошибке
a['Dist'] = (a.subtract(b, level=0)**2).sum(axis=1)**(1/2)
Укладка начальных точек и расчетных точек и сортировка
r = pd.concat([a.reset_index(), start]).sort_values(by = ['Trans', 'Dist'])
print(r)
файл, используемый для данных
Trans Y X Elev
0 TR9 101.5 101.5 5.5
1 TR9 111.0 111.0 8.0
2 TR9 121.0 121.0 6.0
3 TR9 131.0 131.0 7.0
4 TR9 141.0 141.0 4.0
5 TR10 101.0 201.0 2.0
6 TR10 111.0 211.0 6.0
7 TR10 121.0 221.0 5.0
8 TR10 131.0 231.0 7.0
9 TR10 141.0 241.0 8.0
10 GRAND 101.0 301.0 5.0
11 GRAND 111.0 311.0 6.0
12 GRAND 121.0 321.0 7.0
13 GRAND 131.0 331.0 9.0
14 GRAND 141.0 341.0 5.0
15 TR11 101.0 401.0 4.0
16 TR11 111.5 411.5 6.0
17 TR11 121.0 421.0 8.0
18 TR11 131.0 431.0 4.0
19 TR11 141.0 441.0 2.0
файл, используемый для начальных точек
Trans Y X Elev
0 TR9 99.5 99.5 4.0
1 TR10 99.0 199.5 3.2
2 GRAND 99.0 299.5 6.5
3 TR11 99.0 399.5 8.2
4 TR99 999.0 999.0 999.9
Я использую python 3, но новичок в этом. Я могу только понять, как сделать отдельные кадры данных для каждого разреза (a b и c), а затем рассчитать расстояние оттуда. Но в идеале я хотел бы сопоставить идентификатор Transect начальной точки и рассчитать расстояние до последующих точек в фрейме данных для каждого разреза.
Я пробовал .loc на основе имени трансекта и имени трансекта .groupby. Я понимаю, что, вероятно, не очень хорошо описываю свою проблему. Завтра постараюсь опубликовать код.
@RyanS Добро пожаловать в SO, пожалуйста, прочитайте Как спросить о том, как улучшить свой вопрос. Для начала добавьте наборы данных в блоки кода вместо изображения/ссылки на изображение. Кроме того, пожалуйста, четко опишите ожидаемый результат.
Спасибо за обновление вашего вопроса и добавление вашей попытки. Пожалуйста, найдите мое решение, которое должно решить вашу проблему ниже. Вы можете использовать возможности вещания, которые панды предлагают по значениям индекса, чтобы решить эту проблему.
Я вижу, вы немного изменили данные. Пожалуйста, найдите мой обновленный ответ с новым примером набора данных, который вы предоставили в вопросе.
Отметьте решение как решенное, если это решит ваш вопрос. Спасибо.
Спасибо, Акшай Сегал!
рад помочь :)
РЕДАКТИРОВАТЬ. Поскольку вы обновили свой вопрос и изменили данные, имена столбцов и строк, вот решение последнего отредактированного вопроса. Подробное объяснение ниже.
start['Dist'] = 0.0 #Adding Dist column to s
#getting X, Y and setting index to "Trans"
cols = ['X','Y', 'Elev']
a = data.set_index('Trans')[cols]
b = start.set_index('Trans')[cols]
b = b.loc[a.index.unique()] #<--- to ensure that same trans elements exist in both
#Calculating broadcasted distance (by index)
#D = √((Long1-Long2)²+(Lat1-Lat2)²+(Alt1-Alt2)²)
a['Dist'] = list((a.subtract(b, level=0)**2).sum(axis=1)**(1/2))
#Stacking start points and calculated points and sorting
r = pd.concat([a.reset_index(), start]).sort_values(by = ['Trans', 'Dist'])
print(r)
Trans X Y Elev Dist
2 GRAND 299.5 99.0 6.5 0.000000
10 GRAND 301.0 101.0 5.0 4.887740
11 GRAND 311.0 111.0 6.0 17.466826
12 GRAND 321.0 121.0 7.0 30.761827
13 GRAND 331.0 131.0 9.0 45.098670
14 GRAND 341.0 141.0 5.0 59.369100
1 TR10 199.5 99.0 3.2 0.000000
5 TR10 201.0 101.0 2.0 2.773085
6 TR10 211.0 111.0 6.0 16.854970
7 TR10 221.0 121.0 5.0 30.813796
8 TR10 231.0 131.0 7.0 45.063178
9 TR10 241.0 141.0 8.0 59.239261
3 TR11 399.5 99.0 8.2 0.000000
15 TR11 401.0 101.0 4.0 3.201562
16 TR11 411.5 111.5 6.0 16.748134
17 TR11 421.0 121.0 8.0 30.471298
18 TR11 431.0 131.0 4.0 44.648628
19 TR11 441.0 141.0 2.0 58.689863
0 TR9 99.5 99.5 4.0 0.000000
0 TR9 101.5 101.5 5.5 2.915476
1 TR9 111.0 111.0 8.0 16.628289
2 TR9 121.0 121.0 6.0 30.765240
3 TR9 131.0 131.0 7.0 44.972214
4 TR9 141.0 141.0 4.0 59.063525
4 TR99 999.0 999.0 999.9 0.000000
Подробности -
Transect
для каждого фрейма данных и сохраните только столбцы Northing
, Easting
и Elev
.df.subtract
между двумя кадрами данных и установите level=0
. Это означает, что он будет использовать broadcasting
для вычитания всех строк с одним и тем же индексом. Таким образом, 2 строки первой и 1 строка второй с индексом = A
будут вычтены при трансляции, чтобы получить 2 строки. Аналогично другие для каждой функции.square
, просуммируйте его по axis=1
, а затем возьмите square root
, чтобы получить расстояние.D=√((Долгота1-Долгота2)²+(Широта1-Широта2)²+(Alt1-Alt2)²)
['dist']
исходного набора данных.Акшай Сегал, когда я использую этот код в CSV-файле в том же формате, я продолжаю получать сообщение об ошибке " поднять ValueError ("невозможно переиндексировать из дублирующейся оси") ValueError: невозможно переиндексировать из дублирующейся оси " Я предполагаю, что на моем шаге ошибка cols = ['Y','X', 'Elev'] a = data.set_index('Trans')[cols] b = start.set_index('Trans')[cols]
когда вы загружаете данные, «Trans» уже является индексом?
У меня есть столбец высоты, поэтому я использую первый код, который вы мне прислали. Trans уже не является индексом, когда я импортирую
не могли бы вы предоставить скриншот ошибки
Я не могу понять, как добавить скриншот в комментарии. Я куплю тебе "кофе" хоть за твои хлопоты.
о, это мило с твоей стороны. просто добавьте скриншот к вопросу. я увижу это там
Я добавил скриншоты. Я думаю, что обнаружил проблему. Когда мои «Транс» помечены как A B и C, он работает нормально, но если я даю им имя, например ['Транс1', 'Транс2'], я получаю сообщение об ошибке.
Эй, в последнем утверждении вы используете by = ('Transact', 'Dist')
, и это должно быть 'Trans'
последняя строка должна быть r = pd.concat([a.reset_index(), start]).sort_values(by = ['Trans', 'Dist'])
ошибка возникает с этой строкой кода, если у моего транса есть метки A#, но работает, если только алфавитный a['Dist'] = (a.subtract(b, level=0)**2).sum(axis=1)* *(1/2)
также вы можете напечатать a и b? перед строкой с ошибкой
Я не могу воспроизвести ошибку на моем конце. не могли бы вы опубликовать полные данные по вопросу? те, что я вижу на скриншоте? Просто напечатайте data
и start
и скопируйте и вставьте целые таблицы в блок кода в вопросе. Я смогу понять, что не так, только если смогу воспроизвести ту же ошибку.
Ах хорошо, я понял. Проблема в том, что вычисляемый ряд имеет 21 элемент, а исходный - 20. Это потому, что есть дополнительное значение trans
, которое существует только в b, но не в a.
Обновляю свой ответ сейчас.
Изменил серию на список И также добавил двойную проверку для удаления элементов в b, которые не существуют в a.
Это сработало. Еще раз спасибо. Итак, то, что заставило его работать, было правильным списком?
Не только это, но и b = b.loc[a.index.unique()]
. это также вызвало бы проблемы. Список существует, потому что у серии уже был индекс, который отличался от исходного индекса в a. Вот почему, когда вы установили его на a['dist']
, он сказал, что не может переиндексировать.
Какой язык программирования вы используете? Что вы пробовали?