Объединение датафреймов по фиксированному ключу и диапазону
Подскажите, пожалуйста, как можно объединить в pandas датафреймы? У нас есть таблицы, которые необходимо соединить: в первой таблице в качестве ключа указаны "тип объекта" и "км расположения", во второй таблице ключи - "тип объекта" и диапазон участка км (начало, конец).
df1 = pd.DataFrame({'наименование объекта':['Объект 1','Объект 2','Объект 3','Объект 4', 'Объект 5','Объект 6'],
'Тип объекта':['Тип 1', 'Тип 1','Тип 2','Тип 2','Тип 3','Тип 3'],
'км расположения':[101,124,95,301,251,499]
})
df2 = pd.DataFrame({'Тип объекта':['Тип 1','Тип 1','Тип 2','Тип 2','Тип 3','Тип 3','Тип 3'],
'Начало участка, км':[0,200,0,200,0,200,400],
'Конец участка, км':[200,400,200,400,200,400,600],
'Описание':['описание 1','описание 2','описание 1','описание 2','описание 1','описание 2','описание 3']
})
Хочу получить таблицу вида
df1 = pd.DataFrame({'наименование объекта':['Объект 1','Объект 2','Объект 3','Объект 4', 'Объект 5','Объект 6'],
'Тип объекта':['Тип 1', 'Тип 1','Тип 2','Тип 2','Тип 3','Тип 3'],
'км расположения':[101,124,95,301,251,499],
'Описание':['описание 1','описание 1','описание 1','описание 2','описание 2','описание 3']
})
Ответы (2 шт):
Автор решения: CrazyElf
→ Ссылка
А в чём сложность? Если отрезки именно такие всегда, то просто разделить нацело на 200 - и получится id
, по которому датафреймы можно соединить. Рабочий пример на ваших данных:
import pandas as pd
from io import StringIO
data1 = """
наименование объекта Тип объекта км расположения
Объект 1 Тип 1 101
Объект 2 Тип 1 124
Объект 3 Тип 2 95
Объект 4 Тип 2 301
Объект 5 Тип 3 251
Объект 6 Тип 3 499
"""
data2 = """
Тип объекта Начало участка, км Конец участка, км Описание объекта
Тип 1 0 200 описание 1
Тип 1 200 400 описание 2
Тип 2 0 200 описание 1
Тип 2 200 400 описание 2
Тип 3 0 200 описание 1
Тип 3 200 400 описание 2
Тип 3 400 600 описание 3
"""
df1 = pd.read_csv(StringIO(data1), sep='\t')
df2 = pd.read_csv(StringIO(data2), sep='\t')
df1['id'] = df1['км расположения'] // 200
df2['id'] = df2['Начало участка, км'] // 200
df3 = pd.merge(df1, df2, on=['Тип объекта', 'id'])
df3 = df3.drop(columns=['id','Начало участка, км', 'Конец участка, км'])
Результат в df3
:
наименование объекта Тип объекта км расположения Описание объекта
0 Объект 1 Тип 1 101 описание 1
1 Объект 2 Тип 1 124 описание 1
2 Объект 3 Тип 2 95 описание 1
3 Объект 4 Тип 2 301 описание 2
4 Объект 5 Тип 3 251 описание 2
5 Объект 6 Тип 3 499 описание 3
Автор решения: Oopss
→ Ссылка
import pandas as pd
df1 = pd.DataFrame({'наименование объекта':['Объект 1','Объект 2','Объект 3','Объект 4', 'Объект 5','Объект 6'],
'Тип объекта':['Тип 1', 'Тип 1','Тип 2','Тип 2','Тип 3','Тип 3'],
'км расположения':[101,124,95,301,251,499]
})
df2 = pd.DataFrame({'Тип объекта':['Тип 1','Тип 1','Тип 2','Тип 2','Тип 3','Тип 3','Тип 3'],
'Начало участка, км':[0,200,0,200,0,200,400],
'Конец участка, км':[200,400,200,400,200,400,600],
'Описание':['описание 1','описание 2','описание 1','описание 2','описание 1','описание 2','описание 3']
})
#собрать все в один DF
df3 = pd.merge(df1, df2, on='Тип объекта')
#выбрать только где расположение в диапазоне
df3 = df3[(df3['км расположения'] > df3['Начало участка, км']) &
(df3['км расположения'] < df3['Конец участка, км'])]
df3 = df3.drop(columns=['Начало участка, км', 'Конец участка, км'])
print(df3.to_string(index=False))
наименование объекта Тип объекта км расположения Описание
Объект 1 Тип 1 101 описание 1
Объект 2 Тип 1 124 описание 1
Объект 3 Тип 2 95 описание 1
Объект 4 Тип 2 301 описание 2
Объект 5 Тип 3 251 описание 2
Объект 6 Тип 3 499 описание 3