Сегментация по времени и частоте

#python #python-3.x #pandas #dataframe #sklearn-pandas

Вопрос:

Я сгенерировал последние и частотные выходные данные в формате csv из своей модели RFM. Я хотел сегментировать этот вывод таким образом;

 1) Recency

R1  Between 181 and 360 days
R2  Between 121 and 180 days
R3  Between 61 and 120 days
R4  Between 31 and 60 days
R5  Last 30 days
 

Для частоты,

 2) Frequency (number of purchases in the last 12 months):

F1  1 time
F2  Between 2 and 5 times
F3  Between 6 and 9 times
F4  Between 10 and 11 times
F5  12 times or more
 

Я не могу найти решение о том, как создать два новых столбца с указанными выше выводами.

это мои примерные данные;

df_rf->

 frequency     recency
1               179
1               158
1               61
2                82
2               314
 

Результат должен быть таким,

 frequency    recency     Frequency_label                   Recency_label
1               179           F1                           R2
1               158           F1                           R2
1                 61           F1                          R3
2                82            F2                          R3
2                314           F2                          R1
 

Любая помощь в этом будет высоко оценена.

Заранее благодарю вас за поддержку!

Ответ №1:

Не хочу ничего отнимать у ответа @Sonia Samipillai, который выглядит хорошо (и я рад, что вы получили необходимую помощь!), Но я хотел показать другой способ выполнения того же самого, что может привести к более аккуратному коду в целом, особенно в случаях с большим количеством значений для замены, подобных этому.

Для этого мы определяем замены, которые мы хотим сделать в некоторых словарях, а затем переходим к функции pandas between ().

В этом случае (предполагая, что вы хотели сохранить исходные столбцы и добавить новые версии-в противном случае это было бы намного проще!), я думаю, я бы написал что-то вроде:

 import numpy as np

freq_cat_mapping = {(1, 1): 'F1', (2, 5): 'F2', (6, 9): 'F3', (10, 11): 'F4', (12,None,13): 'F5'}
frequency_cats = df_rf['frequency']
for range, value in freq_cat_mapping.items():
    if len(range) == 2:
        frequency_cats = np.where(df_rf['frequency'].between(*range), value, frequency_cats)
    else:
        # This got a bit messy since I had to improvise some Qamp;D logic to handle the open intervals...but it could obviously be improved.
        if range[-1] > range[0]:
            cond = df_rf['frequency'] >= range[0]
        else:
            cond = df_rf['frequency'] <= range[0]
        frequency_cats = np.where(cond, value, frequency_cats)

recency_cat_mapping = {(0, 30): 'R1', (31, 60): 'R2', (61, 120): 'R3', (121, 180): 'R4', (181, 360): 'R5'}
recency_cats = df_rf['recency']
for range, value in recency_cat_mapping.items():
    recency_cats = np.where(df_rf['recency'].between(*range), value, recency_cats)

#Finally, concatanate the new cols
df_rf['frequency_label'] = frequency_cats
df_rf['recency_label'] = recency_cats
 

Ответ №2:

Попробуй :

 df = pd.DataFrame()
df['frequency'] = [1,1,1,2,2]
df['recency'] = [179,158,61,82,314]


#Calculating Frequency labels 

df['Frequency_label'] = np.where((df['frequency'] <= 1), 'F1',
                                 np.where((df['frequency'] >= 2) amp; (df['frequency'] <= 5), 'F2',
                                          np.where((df['frequency'] >= 6) amp; (df['frequency'] <= 9), 'F3',
                                                   np.where((df['frequency'] >= 10) amp; (df['frequency'] <= 11), 'F4',
                                                            np.where((df['frequency'] >= 12), 'F5','NA') ) )))

# Calculating Recency labels
df['Recency_label'] = np.where((df['recency'] >= 181) amp; (df['recency'] <= 360), 'R1',
                                 np.where((df['recency'] >= 121) amp; (df['recency'] <= 180), 'R2',
                                          np.where((df['recency'] >= 61) amp; (df['recency'] <= 120), 'R3',
                                                   np.where((df['recency'] >= 31) amp; (df['recency'] <= 60), 'R4',
                                                            np.where((df['recency'] <= 30), 'R5','NA') ) ))) 
 

Выход:

   frequency recency Frequency_label Recency_label
0   1       179      F1              R2
1   1       158      F1              R2
2   1       61       F1              R3
3   2       82       F2              R3
4   2       314      F2              R1
 

Комментарии:

1. Спасибо Соне за ваш ответ с предложением о том, как получить результат. Примерные данные, безусловно, находятся в пределах моих фактических выходных данных. Просто не знаю, как применить ту же логику в моем фрейме данных! Я постараюсь и посмотрю, получу ли я правильный результат

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

3. вот мои примерные данные : частота появления 1 179 1 158 1 61 2 82 2 314

4. Отредактировал ответ в соответствии с вашими данными. Дайте мне знать, если возникнут какие-либо вопросы. Ты понял это!

5. Спасибо! Я только что протестировал это на своем df, и это сработало как удовольствие.