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类参考上图。

# 文章到此结束,有问题可以一起交流,我们下期文章再见叭