У меня есть два фрейма данных: mp и sp.
mp содержит государственный маршрут (int), отметки ~1/10 мильных столбов (float), широту (float), долготу (float).
route milepost lon lat
2091 2 0.0 -122.189880 47.979063
2667 2 0.1 -122.188067 47.979760
2159 2 0.2 -122.186210 47.979560
1174 2 0.3 -122.184197 47.979098
1878 2 0.4 -122.182098 47.978718
sp имеет маршрут состояния (int), ~ мильный столб (float), где начинается и заканчивается ограничение скорости, а также ограничение скорости (int).
route begin end limit
3119 2 0.000000 0.130000 30
2787 2 0.130000 2.880000 55
3184 2 2.880000 12.080000 60
3035 2 12.080000 12.720000 55
2780 2 12.720000 14.220000 45
2777 2 14.220000 15.450000 35
2774 2 15.450000 21.500000 55
Я хочу иметь один фрейм данных (sp + ограничение скорости), но не могу присоединиться к государственному маршруту и контрольному столбу. Как я могу применить ограничение скорости к каждому столбу в милях в зависимости от интервала? То есть для государственного маршрута 2, верстовой столб 0, 0,1, ограничение скорости = 30; веха 0,2, 0,3, ..., 2,8, ограничение скорости = 55; и т. д.
route milepost lon lat limit
2091 2 0.0 -122.189880 47.979063 30
2667 2 0.1 -122.188067 47.979760 55
2159 2 0.2 -122.186210 47.979560 55
...
2789 2 2.8 -122.134982 47.972241 60
1388 2 2.9 -122.133974 47.970995 60
1609 2 3.0 -122.132964 47.969750 60
Я попробовал объединить панды, но потерял много строк. Пытался выполнить нечеткое объединение с помощью fuzzypanda, но получил сообщение об ошибке, что fuzzypanda.matching не существует (единственный метод, который должен быть!), поэтому невозможно создать нечеткий столбец для слияния. Следующее тоже не получилось:
for route in mp['route']:
for milepost in mp['milepost']:
if (route == sp['route']) & (milepost >= sp['begin']) & (milepost <= sp['end']):
mp.insert(1, 'limit', sp['limit'][0])
Любой подход к проблеме приветствуется; не нужно идти тем путем, которым я пытался! Спасибо!






У меня есть первое решение, чтобы начать все сначала, но с несколькими недостатками:
mp DataFrame построчно с помощью for цикла на основе «справочной» таблицы, предоставленной sp DataFrame.sp для каждой ("state route", "milepost") пары mp DataFrame.Я добавил две строки в ваш mp DataFrame, чтобы mp и sp не имели одинаковую длину.
import pandas as pd
mp_data = {
"state route": [2, 2, 2, 2, 2, 2, 2],
"milepost": [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6],
"latitude": [
-122.18988,
-122.18807,
-122.18621,
-122.1842,
-122.1821,
-122.18,
-122.175,
],
"longitude": [47.97906, 47.97976, 47.97956, 47.9791, 47.97872, 47.978, 47.9775],
}
df_mp = pd.DataFrame(mp_data)
sp_data = {
"state route": [2, 2, 2, 2, 2],
"start speed limit milepost": [0, 0.13, 2.88, 12.08, 12.72],
"stop speed limit milepost": [0.13, 2.88, 12.08, 12.72, 14.22],
"speed limit": [30, 55, 60, 55, 45],
}
df_sp = pd.DataFrame(sp_data)
print(df_mp)
state route milepost latitude longitude
0 2 0.0 -122.18988 47.97906
1 2 0.1 -122.18807 47.97976
2 2 0.2 -122.18621 47.97956
3 2 0.3 -122.18420 47.97910
4 2 0.4 -122.18210 47.97872
5 2 0.5 -122.18000 47.97800
6 2 0.6 -122.17500 47.97750
print(df_sp)
state route start speed limit milepost stop speed limit milepost \
0 2 0.00 0.13
1 2 0.13 2.88
2 2 2.88 12.08
3 2 12.08 12.72
4 2 12.72 14.22
speed limit
0 30
1 55
2 60
3 55
4 45
df_mp DataFramelist_sl = []
# comment: preparing a list that will be filled row by row
# is also an unsatisfactory method that could be improved
for _, row in df_mp.iterrows():
list_sl.append(
(
df_sp["speed limit"].loc[
(row["state route"] == df_sp["state route"])
& (row["milepost"] >= df_sp["start speed limit milepost"])
& (row["milepost"] < df_sp["stop speed limit milepost"])
]
).iloc[0] # works only because we assume that there is exacly one solution
)
df_mp["speed limit"] = list_sl
print(df_mp)
state route milepost latitude longitude speed limit
0 2 0.0 -122.18988 47.97906 30
1 2 0.1 -122.18807 47.97976 30
2 2 0.2 -122.18621 47.97956 55
3 2 0.3 -122.18420 47.97910 55
4 2 0.4 -122.18210 47.97872 55
5 2 0.5 -122.18000 47.97800 55
6 2 0.6 -122.17500 47.97750 55
Извините за изображения. Я пытался предоставить таблицы, но они не сотрудничали, и у меня не было времени разбираться. Я посмотрю, смогу ли я это исправить. Поскольку я не питоник, у меня нет проблем с другим подходом к проблеме. Ваше решение не сработало для моих данных. Я получил сообщение «IndexError: одиночный позиционный индексатор выходит за пределы» в блоке кода «df_sp["ограничение скорости"].loc[".
Я подозреваю, что вы столкнулись со случаем, когда ни одна строка в sp не соответствует определенной записи в mp и, следовательно, iloc[0] выходит за пределы диапазона, поскольку отфильтрованная серия sp["speed limit"] пуста. Возможный патч-обезьяна может состоять в том, чтобы обернуть фрагмент кода list_sl.append(...) в шаблон try ... except и добавить np.NaN при обнаружении ошибки.
Пожалуйста, прочитайте Почему бы не загружать изображения кода в SO, когда задаете вопрос и отредактируйте свой вопрос, чтобы он включал код и данные в виде текста, а не изображений.