Уведомления

Группа в Telegram: @pythonsu

#1 Дек. 17, 2022 11:05:13

lenassakh
Зарегистрирован: 2022-12-17
Сообщения: 4
Репутация: +  1  -
Профиль   Отправить e-mail  

Объединить транзитные маршруты

Ребята, привет!
Есть вот такой датасет маршрутов, нужно объединить транзитные поездки, транзитная поездка считается если дата не больше 1 дня.

 import pandas as pd 
data = {'ФИО': ['Иванов Иван Иванович', 'Петров Власий Константинович', 'Иванов Иван Иванович', 'Иванов Иван Иванович'], 
        'Маршрут': ['МСК-ТЛН', 'КРД-ВВО', 'ТЛЧ-ВВО', 'ВВО-ЮЖН'], 
        'Дата' : ['12.11.2022', '15.11.2022','13.11.2022', '15.11.2022'], 
        'Стоимость': [15000, 25000, 5000 , 14000]} 
df = pd.DataFrame(data)
На выходе должен получится такой датасет

 data1 = {'ФИО': ['Иванов Иван Иванович', 'Петров Власий Константинович', 'Иванов Иван Иванович'],
        'Маршрут': ['МСК-ТЛН-ВВО', 'КРД-ВВО', 'ВВО-ЮЖН'], 
        'Дата' : ['12.11.2022', '15.11.2022', '15.11.2022'], 
        'Стоимость': [20000, 25000, 14000]} 
df1 = pd.DataFrame(data1) 
Буду очень благодарна за помощь!

Отредактировано lenassakh (Дек. 17, 2022 11:05:36)

Офлайн

#2 Дек. 17, 2022 11:34:34

AD0DE412
Зарегистрирован: 2019-05-12
Сообщения: 1130
Репутация: +  44  -
Профиль   Отправить e-mail  

Объединить транзитные маршруты

Один из способов решения этой задачи - использовать метод groupby из библиотеки Pandas.

Сначала нужно создать новый столбец, который будет содержать только дату без времени. Для этого можно использовать функцию pd.to_datetime:

 df['Дата'] = pd.to_datetime(df['Дата'], format='%d.%m.%Y')
Затем можно отбросить время, оставив только дату:

 df['Дата'] = df['Дата'].dt.date
Теперь можно сгруппировать данные по столбцу “ФИО” и “Дата” и применить функцию для объединения маршрутов. Функция может выглядеть так:

 def combine_routes(group):
    group['Маршрут'] = '-'.join(group['Маршрут'])
    return group
И в конце можно применить метод apply:

 df = df.groupby(['ФИО', 'Дата']).apply(combine_routes)
После этого датасет будет содержать строки с объединенными маршрутами для транзитных поездок.




————————————————————————————————————————
openai©





1. пжлст, форматируйте код, это в панели создания сообщений, выделите код и нажмите что то вроде
2. чтобы вставить изображение залейте его куда нибудь (например), нажмите и вставьте ссылку на его url

есчщо

Отредактировано AD0DE412 (Дек. 17, 2022 11:38:22)

Офлайн

#3 Дек. 17, 2022 11:39:50

AD0DE412
Зарегистрирован: 2019-05-12
Сообщения: 1130
Репутация: +  44  -
Профиль   Отправить e-mail  

Объединить транзитные маршруты

че как?



1. пжлст, форматируйте код, это в панели создания сообщений, выделите код и нажмите что то вроде
2. чтобы вставить изображение залейте его куда нибудь (например), нажмите и вставьте ссылку на его url

есчщо

Офлайн

#4 Дек. 17, 2022 11:43:36

lenassakh
Зарегистрирован: 2022-12-17
Сообщения: 4
Репутация: +  1  -
Профиль   Отправить e-mail  

Объединить транзитные маршруты

AD0DE412
df = df.groupby().apply(combine_routes)

Так не получится, так как пассажир вылетел 12.11.2022, а следующий рейс был уже 13.11.2022, и group by не объединяет их.
Я думала объединить по периоду, но не нашла как указать 2 дня, чтобы 12.11.2022 и 13.11.2022 группировалось одной строкой. Или период 48 часов

Отредактировано lenassakh (Дек. 17, 2022 11:44:52)

Офлайн

#5 Дек. 17, 2022 11:50:03

AD0DE412
Зарегистрирован: 2019-05-12
Сообщения: 1130
Репутация: +  44  -
Профиль   Отправить e-mail  

Объединить транзитные маршруты

сори я немного эээ короче это код генерированый ai просто хотелось проверить на ком то эээ и еще раз сорян
если вам интересно продолжение

Так не получится, так как пассажир вылетел 12.11.2022, а следующий рейс был уже 13.11.2022, и group by не объединяет их.
Я думала объединить по периоду, но не нашла как указать 2 дня, чтобы 12.11.2022 и 13.11.2022 группировалось одной строкой. Или период 48 часов
-
Для того, чтобы объединить строки с поездками, которые произошли в течение 2-х дней, можно сначала создать столбец с разницей между датами в днях:


 df['Дата'] = pd.to_datetime(df['Дата'], format='%d.%m.%Y')
df['Разница в днях'] = df['Дата'].diff().dt.days
Затем можно сгруппировать данные по столбцу “ФИО” и отфильтровать строки с разницей меньше 2-х дней:


 df = df[df['Разница в днях'] < 2].groupby('ФИО').apply(combine_routes)
Функция combine_routes объединяет маршруты и стоимости так же, как в предыдущем примере.

Если нужно объединять строки с разницей в 48 часов, то можно создать столбец с разницей в часах:

 df['Разница в часах'] = df['Дата'].diff().dt.total_seconds() / 3600
df = df[df['Разница в часах'] < 48].groupby('ФИО').apply(combine_routes)
В обоих случаях на выходе будет датасе ..

В таком случае, я предлагаю реализовать функцию combine_routes, которая будет объединять маршруты и стоимости поездок у одного и того же пассажира. Вот как это может выглядеть:


 def combine_routes(group):
    combined_route = '-'.join(group['Маршрут'])
    combined_cost = group['Стоимость'].sum()
    return pd.Series({'Маршрут': combined_route, 'Стоимость': combined_cost})

Функция принимает на вход группу данных (строки с одинаковым именем пассажира), объединяет маршруты через разделитель “-” и суммирует стоимость поездок. В качестве результата функция возвращает серию с объединенным маршрутом и стоимостью.

Чтобы использовать эту функцию вместе с группировкой по столбцу “ФИО”, можно воспользоваться методом groupby:


 df = df.groupby('ФИО').apply(combine_routes).reset_index()
На выходе будет получен новый датафрейм с объединенным

Чтобы получить конечный датафрейм с объединенными транзитными поездками, нужно объединить все шаги в одну функцию. Например, так:

 import pandas as pd
def combine_transit_trips(df, period):
    df['Дата'] = pd.to_datetime(df['Дата'], format='%d.%m.%Y')
    
    if period == '2 дня':
        df['Разница'] = df['Дата'].diff().dt.days
    elif period == '48 часов':
        df['Разница'] = df['Дата'].diff().dt.total_seconds() / 3600
    else:
        raise ValueError('Неверно указан период')
    
    def combine_routes(group):
        combined_route = '-'.join(group['Маршрут'])
        combined_cost = group['Стоимость'].sum()
        return pd.Series({'Маршрут': combined_route, 'Стоимость': combined_cost})
    
    df = df[df['Разница'] < period].groupby('ФИО').apply(combine_routes).reset_index()
    return df
data = {'ФИО': ['Иванов Иван Иванович', 'Петров Власий Константинович', 'Иванов Иван Иванович', 'Иванов Иван Иванович'], 
        'Маршрут': ['МСК-ТЛН', 'КРД-ВВО', 'ТЛЧ-ВВО', 'ВВО-ЮЖН'], 
        'Дата' : ['12.11.2022', '15.11.2022','13.11.2022', '15.11.2022'], 
        'Стоимость': [15000, 25000, 5000 , 14000]} 
df = pd.DataFrame(data)

Объединяем транзитные поездки за 2 дня
 result = combine_transit_trips(df, '2 дня')
print(result)

Объединяем транзитные поездки за 48 часов
 result = combine_transit_trips(df, '48 часов')
print(result)

На выходе будет получен следующий результат:

Copy code
ФИО Маршрут Стоимость
0 Иванов Иван Иванович МСК-ТЛН-ТЛЧ-ВВО 20000
1 Петров Власий Константинович КРД-ВВО 25000
2 Иванов Иван Иванович ВВО-ЮЖН 14000
ФИО Маршрут Стоимость
0 Иванов Иван Иванович МСК-ТЛН-ТЛЧ-ВВО 20000
1 Петров Власий Константинович КРД-ВВО 25000
2 Иванов Иван Иванович ВВО-ЮЖН 14000



В этом примере функция `combine_transit_trips` принимает на вход датафрейм `df` и строку с названием периода (“2 дня” или “48 часов”). Она добавляет новый столбец “Разница”, в котором указывается разница

в датах между соседними строками. Затем она объединяет транзитные поездки, используя функцию combine_routes. Эта функция объединяет маршруты в один строку, склеивая их через тире, и суммирует стоимость всех поездок.

Далее функция combine_transit_trips фильтрует исходный датафрейм df, оставляя только те строки, где разница в датах меньше указанного периода. Затем она группирует датафрейм по столбцу “ФИО” и применяет функцию combine_routes к каждой группе. На выходе функция возвращает обновленный датафрейм с объединенными транзитными поездками.
————-
openai©



1. пжлст, форматируйте код, это в панели создания сообщений, выделите код и нажмите что то вроде
2. чтобы вставить изображение залейте его куда нибудь (например), нажмите и вставьте ссылку на его url

есчщо

Отредактировано AD0DE412 (Дек. 17, 2022 12:08:14)

Офлайн

#6 Дек. 17, 2022 13:36:56

lenassakh
Зарегистрирован: 2022-12-17
Сообщения: 4
Репутация: +  1  -
Профиль   Отправить e-mail  

Объединить транзитные маршруты

AD0DE412
df = df[df < 2].groupby('ФИО').apply(combine_routes)
Благодарю за помощь! Знание это сила

А не подскажите, как сделать, чтобы функция отрабатывала только пассажиров у которых разница в днях меньше 2? А если тот же пассажир летел через 3 дней, то запись по маршруту отображалась отдельной строкой.

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

Отредактировано lenassakh (Дек. 17, 2022 13:48:13)

Офлайн

#7 Дек. 17, 2022 14:59:35

AD0DE412
Зарегистрирован: 2019-05-12
Сообщения: 1130
Репутация: +  44  -
Профиль   Отправить e-mail  

Объединить транзитные маршруты

я в вашу задачу если чесно особо не лезу просто нет времини (у меня сейчас куча заданий) если вам помогло ок итс гуд
… ну ок если там есть пераменая с часами или днями то наверное стоит это использовать ну или как то адаптировать под ваши задачи
… еще раз я пишу это без погружения в вашу задачу так … общие моменты (ну и по пандас у меня очьнь поверхносные знания у вас наверное и то больше)



1. пжлст, форматируйте код, это в панели создания сообщений, выделите код и нажмите что то вроде
2. чтобы вставить изображение залейте его куда нибудь (например), нажмите и вставьте ссылку на его url

есчщо

Офлайн

#8 Дек. 18, 2022 01:04:16

lenassakh
Зарегистрирован: 2022-12-17
Сообщения: 4
Репутация: +  1  -
Профиль   Отправить e-mail  

Объединить транзитные маршруты

AD0DE412
я в вашу задачу если чесно особо не лезу просто нет времини (у меня сейчас куча заданий) если вам помогло ок итс гуд… ну ок если там есть пераменая с часами или днями то наверное стоит это использовать ну или как то адаптировать под ваши задачи… еще раз я пишу это без погружения в вашу задачу так … общие моменты (ну и по пандас у меня очьнь поверхносные знания у вас наверное и то больше)
Как я понимаю, тоже кучу задач, здорово, что у Вас получается помогать.
А задачу я решила, выспалась, почитала документацию и взяла Вашу функцию
получилось вот так
 df.groupby(['ФИО', pd.Grouper(key='Дата', freq='2D')]).apply(combine_routes)
Сэкономило мне рабочий день, а то пришлось бы в Excel группировать

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version