Задача для анализа : руководством торговой сети розничных магазинов одежды было принято решение добавить в ассортимент новую позицию - мужские трусы. По прошествии некоторого времени поставлена задача проанализировать продажи с точки
зрения покупательских предпочтений в разрезах пола, возраста, модели и цвета.
зрения покупательских предпочтений в разрезах пола, возраста, модели и цвета.
Для анализа были подготовлены следующие данные :
df = pd.read_excel("data/undpants_sales.xlsx")
df.head()
df.head()
customer_sex customer_age clothing_sex clothing_cat model color
0 male 59 male Jacket NaN NaN 1 female 39 male Jacket NaN NaN 2 female 40 female Trousers NaN NaN 3 female 46 female Trousers NaN NaN 4 female 65 female Trousers NaN NaN
Данные представляют собой продажи в разрезе : пол и возраст покупателя, пол и
товарная группа покупки. Так как цель анализа - мужские трусы, то по ним есть
дополнительная информация - модель и цвет.
Обозначения :
customer_sex - пол покупателя,
customer_age - возраст покупателя,
clothing_sex - пол товарной группы покупки
clothing_cat - товарная группа покупки
model - модель трусов
color - цвет трусов
#Типы переменных
df.dtypes
customer_sex object customer_age int64 clothing_sex object clothing_cat object type object color object dtype: object
#Размер данных
df.shape
(20127, 6)
Выделим колонки с объектными данными
ob_cols = [c for c in df.columns if df[c].dtypes=='O']
ob_cols
['customer_sex', 'clothing_sex', 'clothing_cat', 'model', 'color']
Выведем уникальные значения в этих колонках
for col in ob_cols: print(len(df[col].unique()),df[col].unique())
2 ['male' 'female'] 2 ['male' 'female'] 10 ['Jacket' 'Trousers' 'Sweatshirt' 'Sweater' 'T-shirt' 'Underpants' 'Shirt' 'Shorts' 'Skirt' 'The dress'] 10 [nan 'model1' 'model2' 'model3' 'model4' 'model5' 'model6' 'model7' 'model8' 'model9'] 9 [nan 'blue' 'red' 'black' 'grey' 'indigo' 'dark grey' 'white' 'khaki']Добавим в данные новую колонку - индекс покупки мужских трусов
def f(row): return (1 if row['clothing_sex']=='male' and row['clothing_cat']=='Underpants' else 0)
df['ind'] = df.apply(f, axis=1)
df.head()
customer_sex customer_age clothing_sex clothing_cat model color ind 0 male 59 male Jacket NaN NaN 0 1 female 39 male Jacket NaN NaN 0 2 female 40 female Trousers NaN NaN 0 3 female 46 female Trousers NaN NaN 0 4 female 65 female Trousers NaN NaN 0
Выведем долю продаж трусов в общих продажах :
print('male underwear % : ',round(df.ind.mean(),4))
male underwear % : 0.0589
Посмотрим как покупки мужских трусов распределились по полу покупателяind_sum_by_customer_sex = df.groupby(by='customer_sex')['ind'].sum()ind_sum_by_customer_sex/df.ind.sum()
customer_sex female 0.470042 male 0.529958 Name: ind, dtype: float64Доли в продажах практически равные
Сгруппируем общие продажи и продажи трусов по возрасту и выведем их
распределение
by_age = df.groupby(by='customer_age')['customer_age'].count()
ind_by_age = df.groupby(by='customer_age')['ind'].sum()
ax1 = by_age.plot(grid=True,figsize=(10, 7),title='number of sales')
ax1.set_xlabel('age')
ax1.set_ylabel('all sales',color='b')
ax2 = ax1.twinx()
ax2 = ind_by_age.plot(color='r')
ax2.set_ylabel('Underpants', color='r')
Разделим возраст на интервалы и выведем процент продаж трусов в этих интервалах
df['age_group'] = df['customer_age'].apply(
lambda x: '[15, 30)' if x < 30 else '[30, 40)' if x < 40 \
else '[40, 50)' if x < 50 else '[50, 60)' if x < 60 \
else '[60, 70)' if x < 70 else '70+'
)
Посмотрим, как по возрасту распределилась доля трусов в общих покупках :
У женщин
ind_by_age_group_male = df.query('customer_sex=="female"').
groupby(by='age_group')['ind'].mean() * 100.0
ind_by_age_group_male
age_group 70+ 3.867403 [15, 30) 4.579208 [30, 40) 3.986333 [40, 50) 4.405846 [50, 60) 5.208333 [60, 70) 5.319149 Name: ind, dtype: float64ind_by_age_group_female.plot.bar(title='% of Underpants in total sales (female)')
У мужчин
ind_by_age_group_male = df.query('customer_sex=="male"').
groupby(by='age_group')['ind'].mean() * 100.0
ind_by_age_group_male
age_group 70+ 10.344828 [15, 30) 8.603239 [30, 40) 8.103263 [40, 50) 6.820084 [50, 60) 8.466604 [60, 70) 12.419700 Name: ind, dtype: float64ind_by_age_group_male.plot.bar(title='% of Underpants in total sales (male)')
Доли возрастных групп в общих продажах и в продажах мужских трусов
plt.figure(figsize=(12, 7)) plt.subplot(1, 2, 1) plt.title('all sales') sum_by_age_group.plot( kind='pie', startangle=90, subplots=True, autopct=lambda x: '%0.1f%%' % x ); plt.subplot(1, 2, 2) plt.title('Underpants sales') ind_sum_by_age_group.plot( kind='pie', startangle=90, subplots=True, autopct=lambda x: '%0.1f%%' % x )
Осталось посмотреть, как распределяются продаж в возрастных группах по моделям
и по цветам
Пол - возраст - модель
sex_age_model_df = df.groupby(['age_group','customer_sex',
'model'])['ind'].sum().unstack('model').fillna(0)
sex_age_model_df = sex_age_model_df.divide(
df.groupby(
by=['age_group','customer_sex']
)['ind'].sum(),
axis=0
)
ax=sex_age_model_df.plot.bar(stacked=True)
ax.legend(loc='center right', bbox_to_anchor=(1.3, 0.5), ncol=1)
Пол - возраст - цвет
sex_age_model_df = df.groupby(['age_group','customer_sex', 'color'])['ind'].sum().unstack('color').fillna(0) sex_age_color_df = sex_age_model_df.divide( df.groupby( by=['age_group','customer_sex'] )['ind'].sum(), axis=0 )
ax=sex_age_color_df.plot.bar(stacked=True) ax.legend(loc='center right', bbox_to_anchor=(1.3, 0.5), ncol=1)
Комментариев нет:
Отправить комментарий