TGViewer
Детектив данных Детектив данных @detective_data · 2.79K subscribers
Post #232 2.9K
🐍 Переходы клиентов из канала в канал и диаграмма Санкей
#кодимпитоним
Насмотревшись на Валерию с канала "Мир аналитика данных" решил тоже периодически писать о некоторых моих реальных рабочих задачах на питоне и способе их решения. В комментариях будет выложен питоновский файл чуть расширенный с дополнительными комментариями в коде

Была поставлена задача узнать какие клиенты меняли канал продаж, и в каком месяце. Сейчас посмотрим а так-же построим на основе данных диаграмму Санкей, чтобы понимать визуально, из какого-канала куда переходит клиент (а бонусом превратим диаграмму в гоночный трек 😁 )

Итак представим что у нас есть датасет, со следующими данными
- клиент
- канал
- и месяц - предположим что у нас выгрузка за пол года

Сгенерируем датасет для работы:

import random 
import pandas as pd
import numpy as np

clients = [str(random.randint(1, 999999)) for _ in range(20)]
clients = clients * 6

channels = ['E-com', 'B2B', 'B2C']
channel = [random.choice(channels) for _ in range(120)]

date_month = []
for i in range(2, 8):
date_month.extend([str(i)] * 20)

data = {
'client': clients,
'channel': channel,
'date_month': date_month
}

df = pd.DataFrame(data)

Пробежимся по коду:
1. Создаём список клиентов в количестве 20, и умножаем список на 6, получая подобие выгрузки к которой в дальнейшем добавим месяцы
2. Формируем список из допустим трёх каналов случайным образом в количестве 120, под весь наш датасет
3. формируем месяцы циклом от 2 до 7 месяца - по 20 раз

Начинаем изучать датасет:
Сначала посчитаем сколько каналов было у каждого клиента, а затем присоединим полученную цифру в наш датасет
count_channel = df.groupby('client')['channel'].nunique().rename('unique_channels')
dfmain = df.join(count_channel, on='client', how='left')

Затем добавим метку клиенту - менялся или не менялся у клиента канал, нагляднее это сделать с библиотекой numpy. В нашей случайной выборке скорее всего таких клиентов не будет, но в реальных данных таких клиентов было большинство
dfmain['change_channel'] = np.where(dfmain['unique_channels'] > 1, 'change', 'no change')

Далее в расширенной версии кода мы сохраняем список таких клиентов, но тут места мало, поэтому сразу отсортируем датасет: сначала по клиенту, а потом по месяцу в обратную сторону
dfs = filtered_alldf.sort_values(by=['client', "date_month"], ascending=[True, False])

Убираем дубликаты строк с клиентом и первым каналом, в результате у нас останутся только текущий канал и другие каналы
dfa = dfs.drop_duplicates(subset=['client', 'channel'], keep='first')

С помощью метода cumcount() пронумеруем строки по столбцу клиента, в результате мы получим новый столбец где текущий канал клиента равен 0, второй 1, и тд. Дальше фильтруем таблицу только где значение из нового столбца равно 1, т.е. строку с предыдущим каналом и месяцем его смены
dfa['line'] = dfa.groupby('client').cumcount()
result_df = dfa[dfa['line'] == 1]

Вот в целом мы и решили задачу, осталось всё переименовать столбцы, смёржить, и убрать предыдущие месяцы
result_df = result_df.rename(columns={"channel": "last_channel", "date_month": "last_date_month"})
dfmain5 = pd.merge(dfmain, result_df[['client', 'last_channel', 'last_date_month']], on='client', how='left')
dfmain5 = dfmain5[dfmain5['date_month'] == '7']


Код на график будет в комментариях. График Санкей (шарфы или перетоки) я очень люблю, но он не на всех данных хорошо смотрится. Тут прямо идеально зашёл. (Максимально упрощенный вариант графика в прилагаемом ipynb файле в комментах)

Спасибо за просмотр, если такой формат вам понравился - ставьте лайк.
  • ❤ 38
  • 👍 21
  • 🔥 11
More from @detective_data
  1. Sep 28, 2026Айтишники, горит вакансия ❗️ Позиция: Дата-аналитик Компания: Aviasales Зарплата: 200,000-…
  2. Sep 16, 2026Ну а пока нет ссылки на линк, держите немножко балканской природы)
  3. Sep 16, 2026Да я легко зарегистрируюсь на линке. Тем временем линкедин... Короче как я понял новичков…
  4. Sep 8, 2026А тем временем небольшая смена локации. Отпуск как никак 😁
  5. Aug 25, 2026🕵 Всем привет. Ох, как я люблю подобные письма. Вычислят напрямую или по ответам. В какую…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →