Канал про "Аналитику Данных" и мой путь в профессию.
Вкатился после 33
Ныне работаю BI аналитиком в "Комусе"
Бывший промышленный альпинист, военный юрист, оперуполномоченный, директор, торг представитель, супервайзер и даже HR BP.
Связь: @janet_noir
Post #232
2.9K

🐍 Переходы клиентов из канала в канал и диаграмма Санкей
#кодимпитоним
Насмотревшись на Валерию с канала "Мир аналитика данных" решил тоже периодически писать о некоторых моих реальных рабочих задачах на питоне и способе их решения. В комментариях будет выложен питоновский файл чуть расширенный с дополнительными комментариями в коде
Была поставлена задача узнать какие клиенты меняли канал продаж, и в каком месяце. Сейчас посмотрим а так-же построим на основе данных диаграмму Санкей, чтобы понимать визуально, из какого-канала куда переходит клиент (а бонусом превратим диаграмму в гоночный трек 😁 )
Итак представим что у нас есть датасет, со следующими данными
- клиент
- канал
- и месяц - предположим что у нас выгрузка за пол года
Сгенерируем датасет для работы:
Пробежимся по коду:
1. Создаём список клиентов в количестве 20, и умножаем список на 6, получая подобие выгрузки к которой в дальнейшем добавим месяцы
2. Формируем список из допустим трёх каналов случайным образом в количестве 120, под весь наш датасет
3. формируем месяцы циклом от 2 до 7 месяца - по 20 раз
Начинаем изучать датасет:
Сначала посчитаем сколько каналов было у каждого клиента, а затем присоединим полученную цифру в наш датасет
Затем добавим метку клиенту - менялся или не менялся у клиента канал, нагляднее это сделать с библиотекой numpy. В нашей случайной выборке скорее всего таких клиентов не будет, но в реальных данных таких клиентов было большинство
Далее в расширенной версии кода мы сохраняем список таких клиентов, но тут места мало, поэтому сразу отсортируем датасет: сначала по клиенту, а потом по месяцу в обратную сторону
Убираем дубликаты строк с клиентом и первым каналом, в результате у нас останутся только текущий канал и другие каналы
С помощью метода cumcount() пронумеруем строки по столбцу клиента, в результате мы получим новый столбец где текущий канал клиента равен 0, второй 1, и тд. Дальше фильтруем таблицу только где значение из нового столбца равно 1, т.е. строку с предыдущим каналом и месяцем его смены
Вот в целом мы и решили задачу, осталось всё переименовать столбцы, смёржить, и убрать предыдущие месяцы
Код на график будет в комментариях. График Санкей (шарфы или перетоки) я очень люблю, но он не на всех данных хорошо смотрится. Тут прямо идеально зашёл. (Максимально упрощенный вариант графика в прилагаемом ipynb файле в комментах)
Спасибо за просмотр, если такой формат вам понравился - ставьте лайк.
#кодимпитоним
Насмотревшись на Валерию с канала "Мир аналитика данных" решил тоже периодически писать о некоторых моих реальных рабочих задачах на питоне и способе их решения. В комментариях будет выложен питоновский файл чуть расширенный с дополнительными комментариями в коде
Была поставлена задача узнать какие клиенты меняли канал продаж, и в каком месяце. Сейчас посмотрим а так-же построим на основе данных диаграмму Санкей, чтобы понимать визуально, из какого-канала куда переходит клиент (а бонусом превратим диаграмму в гоночный трек 😁 )
Итак представим что у нас есть датасет, со следующими данными
- клиент
- канал
- и месяц - предположим что у нас выгрузка за пол года
Сгенерируем датасет для работы:
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






















