coffee销售数据集分析:基于时间趋势分析的实操练习
**文章说明:**对coffee销售数据集的简单分析练习(时间趋势分析练习),主要是为了强化利用python进行数据分析的实操能力。属于个人的练习文章。
**注:**这是我第一次使用md格式编辑博客文章,排版上还是不是很熟悉,害,我尽量弄好看点。
分析过程
import pandas as pd
import matplotlib.pyplot as plt
# 设置中文字体,防止绘图时中文标题出现乱码
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# 导入数据
data = pd.read_csv(r"C:\Users\31049\Desktop\电商数据\coffee.csv")
# 查看数据情况
print(data.shape)
data.head()
(2623, 6)
date | datetime | cash_type | card | money | coffee_name | |
---|---|---|---|---|---|---|
0 | 2024-03-01 | 2024-03-01 10:15:50.520 | card | ANON-0000-0000-0001 | 38.7 | Latte |
1 | 2024-03-01 | 2024-03-01 12:19:22.539 | card | ANON-0000-0000-0002 | 38.7 | Hot Chocolate |
2 | 2024-03-01 | 2024-03-01 12:20:18.089 | card | ANON-0000-0000-0002 | 38.7 | Hot Chocolate |
3 | 2024-03-01 | 2024-03-01 13:46:33.006 | card | ANON-0000-0000-0003 | 28.9 | Americano |
4 | 2024-03-01 | 2024-03-01 13:48:14.626 | card | ANON-0000-0000-0004 | 38.7 | Latte |
# 检查数据类型、检查是否有缺失值
print(data.info())
# 输出缺失值数量
print('\n缺失值数量:')
print( data.isnull().sum())
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2623 entries, 0 to 2622
Data columns (total 6 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 date 2623 non-null object
1 datetime 2623 non-null object
2 cash_type 2623 non-null object
3 card 2534 non-null object
4 money 2623 non-null float64
5 coffee_name 2623 non-null object
dtypes: float64(1), object(5)
memory usage: 123.1+ KB
None
缺失值数量:
date 0
datetime 0
cash_type 0
card 89
money 0
coffee_name 0
dtype: int64
发现1: card列有89个缺失值,可能有些用户不是使用card支付,而是其他支付方式。(待验证)
发现2: date和datetime列的数据类型为object类型,需要转化为日期类型
# 转化为datetime日期格式
data['date'] = pd.to_datetime(data['date'])
data['datetime'] = pd.to_datetime(data['datetime'])
# 异常值检查,检查monet列是否有0值或负值
data['money'].describe()
结果:最小值大于0,因此无异常值。
一、付款方式分析:观察‘支付方式’的趋势
# 计算不同支付方式的数量以及占比。
ty = data['cash_type'].value_counts()
# 可视化
plt.pie(ty, labels=ty.index, autopct=lambda pct: f'{int(pct/100*ty.sum())}, {pct:.1f}%')
plt.title('不同支付方式的数量以及占比')
plt.show()
结论:支付方式只有两种(cash和card),96%的用户选择使用“card”进行支付。也说明了card列的89个缺失值是合理的(因为89个订单数据显示cash现金支付)
分析用户选择的支付方式随时间的变化趋势:
from datetime import datetime
# 提取月份
data['month'] = data['date'].dt.month
# unstack()方法用于将行索引转为列,或者更准确地说,是将 DataFrame 中的层次化索引的某一层转换为列
payment_counts = data.groupby(['month', 'cash_type']).size().unstack(fill_value=0)
payment_counts.index = payment_counts.index.astype(str)
# 查看结果
print(payment_counts)
cash_type card cash
month
3 175 31
4 168 28
5 241 26
6 223 4
7 237 0
8 272 0
9 344 0
10 426 0
11 259 0
12 189 0
结果可视化:
# 创建一个图形容器、子图对象
fig, ax = plt.subplots(figsize=(8, 5))
# 绘制cash-card订单数量的柱状图
ax.bar(payment_counts.index, payment_counts['cash'], label='cash现金', color='blue')
ax.bar(payment_counts.index, payment_counts['card'], bottom=payment_counts['cash'], label='card', color='skyblue')
# 同一坐标系下绘制每月的cash现金数量占比的折线图
ax1 = ax.twinx()
ax1.set_ylim([0, 0.5])
cash_pct = (payment_counts['cash'] / (payment_counts['card'] + payment_counts['cash'])).round(2)
ax1.plot(payment_counts.index, cash_pct, label='cash占比', marker='^', color='r')
for i in range(len(payment_counts)):
ax1.text(payment_counts.index[i], cash_pct.iloc[i], s=f'{cash_pct.iloc[i]}%')
ax.legend(loc='upper left')
ax1.legend(loc='best')
plt.title('cash-card数量的堆积柱状图\n每月的cash现金数量占比', fontsize=15)
ax.set_xlabel('month月份')
ax.set_ylabel('数量')
plt.show()
结论:在3-6月,cash现金支付的订单数占比逐月下降,且之后几个月全部订单都是使用card卡支付的,呈现出无现金支付的趋势。
二、销售趋势分析:热销时间段(时间趋势)
# 定义设置时间段的函数,[0-6,6-8,8-12,12-14,14-18,18-21,21-0], 对应[凌晨、早晨、早上、中午、下午、晚上、深夜]
def f(hour):
if hour<6:
return '凌晨'
elif hour<8:
return '早晨'
elif hour<12:
return '早上'
elif hour<14:
return '中午'
elif hour<18:
return '下午'
elif hour<21:
return '晚上'
else:
return '深夜'
# 增加一列表示时间段
data['time'] = data['datetime'].dt.hour.apply(f)
# 查看数据
data.head()
date | datetime | cash_type | card | money | coffee_name | month | time | |
---|---|---|---|---|---|---|---|---|
0 | 2024-03-01 | 2024-03-01 10:15:50.520 | card | ANON-0000-0000-0001 | 38.7 | Latte | 3 | 早上 |
1 | 2024-03-01 | 2024-03-01 12:19:22.539 | card | ANON-0000-0000-0002 | 38.7 | Hot Chocolate | 3 | 中午 |
2 | 2024-03-01 | 2024-03-01 12:20:18.089 | card | ANON-0000-0000-0002 | 38.7 | Hot Chocolate | 3 | 中午 |
3 | 2024-03-01 | 2024-03-01 13:46:33.006 | card | ANON-0000-0000-0003 | 28.9 | Americano | 3 | 中午 |
4 | 2024-03-01 | 2024-03-01 13:48:14.626 | card | ANON-0000-0000-0004 | 38.7 | Latte | 3 | 中午 |
# 计算不同时间段的订单数量占比
nums_time = data.groupby('time').size().sort_values()
# 可视化
plt.pie(nums_time, labels=nums_time.index, autopct=lambda pct: f'{int(pct/100*nums_time.sum())}\n{pct:.1f}%', radius=1)
plt.title('不同时间段的订单数及其占比')
plt.show()
结论:店铺早上(8-12点)的订单数最多,占比31%;第二下午(14-18点)占比24%;第三是晚上(18-21点)占比18%。这3个时间段占比总和近75%。
三、咖啡销量分析:某时间段最畅销的咖啡(最受欢迎)
# 按照['time', 'coffee_name']分组,计算每组包含的销量数据,并通过unstack()方法转化行层次化索引(['time', 'coffee_name'])的‘coffee’索引转为列
cof_time = data.groupby(['time', 'coffee_name']).size().unstack(fill_value=0)
# 查看数据
cof_time
coffee_name | Americano | Americano with Milk | Cappuccino | Cocoa | Cortado | Espresso | Hot Chocolate | Latte |
---|---|---|---|---|---|---|---|---|
time | ||||||||
下午 | 86 | 124 | 95 | 36 | 43 | 31 | 52 | 160 |
中午 | 62 | 93 | 45 | 15 | 38 | 18 | 13 | 70 |
早上 | 114 | 226 | 80 | 38 | 127 | 32 | 34 | 180 |
早晨 | 7 | 12 | 10 | 3 | 2 | 2 | 0 | 29 |
晚上 | 39 | 92 | 103 | 30 | 22 | 10 | 63 | 110 |
深夜 | 19 | 74 | 35 | 17 | 15 | 4 | 44 | 69 |
分时间段进行可视化:
# 创建一个图形对象fig、包含1*6张子图的ax对象
fig, ax = plt.subplots(6, 1, figsize=(6, 30))
# 绘制每个时间段的销量柱状图
for i in range(len(cof_time)):
# cof_time的取每行数据,并排序,用于可视化
d = cof_time.iloc[i].sort_values(ascending=False)
ax[i].bar(d.index, d.values, color='skyblue')
ax[i].tick_params(axis='x', rotation=45) #tick_params()可以调整刻度线的位置、大小、颜色、旋转、刻度标签的对齐方式、字体大小等
ax[i].set_title(f'{cof_time.index[i]}——热销的coffee')
ax[i].set_ylabel('销量')
ax[i].grid(axis='y', alpha=0.5)
fig.tight_layout()
plt.show()
结论:每个时间段最受欢迎的coffee类参考上图。
# 文章到此结束,有问题可以一起交流,我们下期文章再见叭