Как объединить два кадра данных за интервал?

У меня есть два фрейма данных: 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])

Любой подход к проблеме приветствуется; не нужно идти тем путем, которым я пытался! Спасибо!

Пожалуйста, прочитайте Почему бы не загружать изображения кода в SO, когда задаете вопрос и отредактируйте свой вопрос, чтобы он включал код и данные в виде текста, а не изображений.

Nick 01.05.2024 03:20
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

У меня есть первое решение, чтобы начать все сначала, но с несколькими недостатками:

  • не на 100% Pythonic, поскольку он по-прежнему анализирует ваш 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 DataFrame

list_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[".

J. Sizzler 01.05.2024 20:14

Я подозреваю, что вы столкнулись со случаем, когда ни одна строка в sp не соответствует определенной записи в mp и, следовательно, iloc[0] выходит за пределы диапазона, поскольку отфильтрованная серия sp["speed limit"] пуста. Возможный патч-обезьяна может состоять в том, чтобы обернуть фрагмент кода list_sl.append(...) в шаблон try ... except и добавить np.NaN при обнаружении ошибки.

qmarolleau 01.05.2024 21:56

Другие вопросы по теме