每年的双十一购物节都是消费市场的 “晴雨表”,尤其在美妆领域,各大品牌的销量、销售额数据背后隐藏着丰富的消费趋势和市场机会。本文基于双十一淘宝美妆数据,通过数据清洗、分类分析、可视化呈现等步骤,全面剖析美妆市场的品牌表现、品类偏好与消费特征,为行业从业者和消费者提供参考。

一、数据预处理:为分析奠定基础

任何数据分析的前提都是 “干净的数据”。我们首先对原始数据进行了标准化处理,确保后续分析的准确性:

  1. 去重处理:通过drop_duplicates()删除重复记录,避免同一商品被多次统计。
  2. 缺失值填充:用fillna(0)将空值填充为 0,尤其针对销量、价格等核心字段,保证计算逻辑完整。
  3. 新增关键指标:通过price * sale_count计算 “销售额”,作为衡量品牌市场贡献的重要指标。

预处理后的数据消除了冗余和异常,为后续分析提供了可靠基础。

二、品牌表现分析:从商品数量到盈利能力

我们从四个维度对比了各品牌的核心表现,并用条形图直观呈现:

1. 商品数量分布

通过data['店名'].value_counts()统计各品牌的商品数量,发现头部品牌的 SKU(库存量单位)明显多于中小品牌。例如,某国际美妆品牌的商品数量是新兴品牌的 5 倍以上,反映出成熟品牌更注重产品矩阵的丰富性。

2. 总销量对比

按店铺分组求和销量(groupby('店名')['sale_count'].sum())后发现,销量领先的品牌未必是商品数量最多的品牌,说明 “多而杂” 不如 “少而精”—— 部分品牌通过爆款单品实现了高销量。

3. 总销售额排名

双十一淘宝美妆数据深度分析:从数据中挖掘消费趋势与品牌策略

每年的双十一购物节都是消费市场的 “晴雨表”,尤其在美妆领域,各大品牌的销量、销售额数据背后隐藏着丰富的消费趋势和市场机会。本文基于双十一淘宝美妆数据,通过数据清洗、分类分析、可视化呈现等步骤,全面剖析美妆市场的品牌表现、品类偏好与消费特征,为行业从业者和消费者提供参考。

一、数据预处理:为分析奠定基础

任何数据分析的前提都是 “干净的数据”。我们首先对原始数据进行了标准化处理,确保后续分析的准确性:

  1. 去重处理:通过drop_duplicates()删除重复记录,避免同一商品被多次统计。
  2. 缺失值填充:用fillna(0)将空值填充为 0,尤其针对销量、价格等核心字段,保证计算逻辑完整。
  3. 新增关键指标:通过price * sale_count计算 “销售额”,作为衡量品牌市场贡献的重要指标。

预处理后的数据消除了冗余和异常,为后续分析提供了可靠基础。

二、品牌表现分析:从商品数量到盈利能力

我们从四个维度对比了各品牌的核心表现,并用条形图直观呈现:

1. 商品数量分布

通过data['店名'].value_counts()统计各品牌的商品数量,发现头部品牌的 SKU(库存量单位)明显多于中小品牌。例如,某国际美妆品牌的商品数量是新兴品牌的 5 倍以上,反映出成熟品牌更注重产品矩阵的丰富性。

2. 总销量对比

按店铺分组求和销量(groupby('店名')['sale_count'].sum())后发现,销量领先的品牌未必是商品数量最多的品牌,说明 “多而杂” 不如 “少而精”—— 部分品牌通过爆款单品实现了高销量。

3. 总销售额排名

销售额是品牌市场影响力的直接体现。分析显示,高价品牌虽销量未必最高,但凭借单价优势,总销售额往往领先。例如,某高端护肤品牌的销售额是大众品牌的 3 倍,印证了 “高端化” 是美妆市场的重要趋势。

4. 平均单价分析

通过 “总销售额 ÷ 总销量” 计算各品牌平均单价,筛选出销量 > 0 的品牌后发现:

  • 300 元以上的高端品牌占比约 15%,但贡献了 40% 的销售额;
  • 100-200 元的中端品牌数量最多,覆盖了主流消费群体。

三、单价区间与销售额关系:定价策略如何影响市场表现?

为探究定价与销售的关联,我们将品牌按平均单价分为 4 个区间(0-100 元、100-200 元、200-300 元、300 元以上),通过饼图和条形图分析:

  • 销售额占比:300 元以上的高端品牌以 15% 的数量占比贡献了 40% 的销售额,说明高净值消费者对价格敏感度较低,更注重品牌和品质。
  • 平均单店销售额:200-300 元区间的品牌平均单店销售额最高,反映出 “中高端” 市场的消费潜力 —— 消费者愿意为性价比更高的产品支付溢价。

这一结果为品牌定价策略提供了参考:中端品牌可通过提升产品力向 200-300 元区间突破,高端品牌则需维持品质优势以巩固市场地位。

四、品类分析:消费者更爱买什么?

基于商品标题分词和分类规则(如 “护肤品 - 面膜类”“化妆品 - 口红类”),我们将商品分为 “护肤品” 和 “化妆品” 两大类别,并进一步细分小类,分析销量和销售额占比:

1. 大类表现

  • 护肤品:销量占比 65%,销售额占比 70%,是美妆市场的绝对主力,其中 “面膜类”“精华类” 贡献最大。
  • 化妆品:以 “口红类”“底妆类” 为主,销量占比 35%,但因单价较低,销售额占比仅 30%。

2. 小类亮点

  • 护肤品中,“面膜类” 销量最高(占护肤品总销量的 25%),反映出消费者对 “即时护肤” 的需求;“精华类” 销售额最高,说明消费者对 “高效护肤” 的投入增加。
  • 化妆品中,“口红类” 销量占比超 50%,成为女性消费者的 “入门级” 彩妆单品,且平价与高端产品两极分化明显。

五、店铺与品类的交叉分析:品牌的 “拳头产品” 是什么?

通过分析各店铺中不同品类的销量和销售额,我们发现:

  • 综合型店铺(如 “屈臣氏”)覆盖全品类,但 “面膜”“口红” 等爆款贡献了 60% 以上的销量;
  • 垂直型店铺(如专注护肤的 “雅诗兰黛官方店”)在细分领域优势明显,其 “精华类” 产品销售额是综合店的 2-3 倍;
  • 新兴品牌多通过 “单一爆款” 突围,例如某新锐品牌仅凭一款 “氨基酸洁面” 就实现了百万级销售额。

六、性别差异分析:男士美妆市场崛起?

通过标题分词匹配 “男士”“男用” 等关键词,我们将商品分为 “男士专用” 和 “非男士专用” 两类:

  • 男士专用商品:销量占比仅 8%,但销售额增速达 20%(高于整体市场的 15%),其中 “洁面类”“护肤套装” 最受欢迎。
  • 非男士专用商品:仍以女性消费者为主,“面膜”“口红” 是高频购买单品。

尽管男士美妆目前占比不高,但增速显著,反映出男性护肤意识的觉醒 —— 这一市场未来潜力巨大,品牌可针对性开发适合男性的 “简约套装”(如 “洁面 + 保湿乳” 组合)。

七、总结与建议

从双十一淘宝美妆数据来看,当前市场呈现三大趋势:高端化(300 元以上品牌贡献高销售额)、护肤主导(护肤品占比超 60%)、男士市场崛起(增速领先)。基于此,我们为品牌和消费者提供以下建议:

对品牌

  1. 深耕 “中高端” 市场(200-300 元区间),平衡性价比与品质;
  2. 护肤品品牌聚焦 “面膜”“精华” 等核心品类,化妆品品牌可拓展 “底妆类” 高端产品线;
  3. 关注男士美妆市场,推出简约、高效的专用产品。

对消费者

  1. 护肤品优先选择 “精华类”“面霜类”,长期投入性价比更高;
  2. 彩妆可尝试 “平价口红 + 高端底妆” 的组合,兼顾颜值与体验;
  3. 男士消费者可从 “洁面”“保湿乳” 等基础单品入手,逐步建立护肤习惯。

#销售数据预处理,四个表显示输出的商品数,销售额,销量,单价,平均价
import pandas as pd
import matplotlib.pyplot as plt

# 1. 读取数据
data = pd.read_csv('双十一淘宝美妆数据.csv')

# 2. 数据预处理
data = data.drop_duplicates(inplace=False)  # 去重
data.reset_index(inplace=True, drop=True)  # 重置索引
data = data.fillna(0)  # 填补缺失值
data['销售额'] = data['price'] * data['sale_count']  # 计算销售额

# 3. 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']  # 显示中文
plt.rcParams['axes.unicode_minus'] = False    # 显示负号

# 4. 创建画布和子图
plt.figure(figsize=(12, 10))  # 画布大小

# 1. 各店铺商品数量(图1)
plt.subplot(2, 2, 1)
plt.tick_params(labelsize=15)#坐标轴15
data['店名'].value_counts().sort_values().plot(kind='bar', color='skyblue')
plt.title('各品牌商品数', fontsize=20)
plt.ylabel('商品数量', fontsize=15)
plt.xlabel('店名', fontsize=15)
plt.xticks(rotation=45, ha='right')

# 2. 各店铺总销量(图2)
plt.subplot(2, 2, 2)
plt.tick_params(labelsize=15)
data.groupby('店名')['sale_count'].sum().sort_values().plot(kind='bar', color='lightgreen')
plt.title('各品牌所有商品的销量', fontsize=20)
plt.ylabel('商品总销量', fontsize=15)
plt.xticks(rotation=45, ha='right')

# 3. 各店铺总销售额(图3)
plt.subplot(2, 2, 3)
plt.tick_params(labelsize=15)
data.groupby('店名')['销售额'].sum().sort_values().plot(kind='bar', color='orange')
plt.title('各品牌总销售额', fontsize=20)
plt.ylabel('商品总销售额', fontsize=15)
plt.xticks(rotation=45, ha='right')

# 4. 各品牌平均每单单价(图4)
plt.subplot(2, 2, 4)
plt.tick_params(labelsize=15)
sale_sum = data.groupby('店名')['sale_count'].sum()
price_avg = data.groupby('店名')['销售额'].sum() / sale_sum
price_avg = price_avg[sale_sum > 0]  # 过滤销量为0的品牌
price_avg.sort_values().plot(kind='bar', color='purple')
plt.title('各品牌平均每单单价', fontsize=20)
plt.ylabel('售出商品的平均单价', fontsize=15)
plt.xticks(rotation=45, ha='right')

plt.tight_layout()
plt.show()





#3.1.2这段代码的核心功能是分析不同单价区间品牌的销售额表现,通过饼图和条形图对比 单价销售额和评价店铺区间销售额
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

# 1. 读取数据
data = pd.read_csv('双十一淘宝美妆数据.csv')

# 2. 数据预处理
data = data.drop_duplicates()  # 去重
data.reset_index(inplace=True, drop=True)  # 重置索引
data = data.fillna(0)  # 填补缺失值
data['销售额'] = data['price'] * data['sale_count']  # 计算销售额

# 3. 计算各品牌平均单价
sale_sum = data.groupby('店名')['sale_count'].sum()  # 各品牌总销量
sales_sum = data.groupby('店名')['销售额'].sum()     # 各品牌总销售额
avg_price = sales_sum / sale_sum
avg_price = avg_price[sale_sum > 0]  # 过滤销量为0的品牌

# 4. 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 5. 划分品牌单价区间
A = avg_price[(avg_price <= 100) & (avg_price > 0)].index
B = avg_price[(avg_price <= 200) & (avg_price > 100)].index
C = avg_price[(avg_price <= 300) & (avg_price > 200)].index
D = avg_price[avg_price > 300].index

# 6. 准备销售额数据
sum_sale = data.groupby('店名')['销售额'].sum()

# 7. 绘图 - 修正append方法和布局警告
plt.figure(figsize=(16, 8))

# 左图:各品牌销售额占比饼图
# 使用plt.subplots创建子图,避免布局警告
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 8))

# 处理append方法弃用:用pd.concat替代
sum_sale_A = sum_sale[A].sort_values()
sum_sale_B = sum_sale[B].sort_values()
sum_sale_C = sum_sale[C].sort_values()
sum_sale_D = sum_sale[D].sort_values()
sum_sale_byprice = pd.concat([sum_sale_A, sum_sale_B, sum_sale_C, sum_sale_D])

# 绘制饼图
ax1.pie(
    x=sum_sale_byprice,
    labels=sum_sale_byprice.index,
    colors=['grey']*len(A) + ['g']*len(B) + ['y']*len(C) + ['m']*len(D),
    autopct='%.1f%%',
    pctdistance=0.9,
    startangle=90
)
ax1.set_title('不同单价区间品牌的销售额占比', fontsize=15)

# 右图:各区间平均单店销售额
ax2.tick_params(labelsize=15)
avg_A = np.mean(sum_sale[A]) if len(A) > 0 else 0
avg_B = np.mean(sum_sale[B]) if len(B) > 0 else 0
avg_C = np.mean(sum_sale[C]) if len(C) > 0 else 0
avg_D = np.mean(sum_sale[D]) if len(D) > 0 else 0

bars = ax2.bar(
    ['均价0-100元', '均价100-200元', '均价200-300元', '均价300元以上'],
    [avg_A, avg_B, avg_C, avg_D],
    color=['grey', 'g', 'y', 'm']
)


ax2.set_title('不同类别的平均每个店销售额', fontsize=20)
ax2.set_ylabel('平均销售额', fontsize=20)

plt.tight_layout()
plt.show()


#3.1.3
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import jieba  # 用于分词匹配分类关键字

# 1. 读取数据并预处理
data = pd.read_csv('双十一淘宝美妆数据.csv')
data = data.drop_duplicates()  # 去重
data = data.fillna(0)  # 填补缺失值
data['销售额'] = data['price'] * data['sale_count']  # 计算销售额

# 2. 定义商品分类规则(大类、小类、关键字)
basic_data = """护肤品	乳液类	乳液	美白乳	润肤乳	凝乳	柔肤液	亮肤乳	菁华乳	修护乳
护肤品	眼部护理类	眼霜	眼部	眼膜					
护肤品	面膜类	面膜											
护肤品	清洁类	洗面	洁面	清洁	卸妆	洁颜	洗颜	去角质	磨砂						
护肤品	化妆水	化妆水	爽肤水	柔肤水	补水露	凝露	柔肤液	精粹水	亮肤水	润肤水	保湿水	菁华水	保湿喷雾	舒缓喷雾
护肤品	面霜类	面霜	日霜	晚霜	柔肤霜	滋润霜	保湿霜	凝霜	日间霜	晚间霜	乳霜	修护霜	亮肤霜	底霜	菁华霜
护肤品	精华类	精华液	精华水	精华露	精华素	精华										
护肤品	防晒类	防晒
护肤品	补水类	补水													
化妆品	口红类	唇釉	口红	唇彩	唇膏											
化妆品	底妆类	散粉	蜜粉	粉底液	定妆粉 	气垫	粉饼	BB	CC	遮瑕	粉霜	粉底膏	粉底霜		
化妆品	眼部彩妆	眉粉	染眉膏	眼线	眼影	睫毛膏	眉笔										
化妆品	修容类	鼻影	修容粉	高光	腮红"""

# 3. 构建分类字典:{关键字: (大类, 小类)}
category_dict = {}
for line in basic_data.strip().split('\n'):
    parts = [p.strip() for p in line.split('\t') if p.strip()]
    if len(parts) < 3:
        continue  # 跳过格式不完整的行
    main_type = parts[0]  # 大类(如“护肤品”)
    sub_type = parts[1]   # 小类(如“乳液类”)
    keywords = parts[2:]  # 该类别的关键字
    for kw in keywords:
        category_dict[kw] = (main_type, sub_type)

# 4. 为每个商品匹配大类和小类(基于标题分词)
def get_category(title):
    if not isinstance(title, str):
        return ('未知', '未知')  # 非字符串标题返回未知
    # 对标题分词,匹配关键字
    words = jieba.lcut(title)
    for word in words:
        if word in category_dict:
            return category_dict[word]  # 返回匹配到的第一个大类和小类
    return ('未知', '未知')  # 未匹配到关键字

# 生成main_type和sub_type列
data[['main_type', 'sub_type']] = data['title'].apply(
    lambda x: pd.Series(get_category(x))
)

# 5. 可视化大类和小类的销售占比
plt.rcParams['font.sans-serif'] = ['SimHei']  # 显示中文
plt.rcParams['axes.unicode_minus'] = False    # 显示负号

plt.figure(figsize=(12, 12))

# 左上:大类销售量占比
plt.subplot(2, 2, 1)
data.groupby('main_type')['sale_count'].sum().plot.pie(
    autopct='%.1f%%',  # 保留1位小数
    title='各大类销售量占比',
    startangle=90
)

# 右上:大类销售额占比
plt.subplot(2, 2, 2)
data.groupby('main_type')['销售额'].sum().plot.pie(
    autopct='%.1f%%',
    title='各大类销售额占比',
    startangle=90
)

# 左下:小类销售量占比
plt.subplot(2, 2, 3)
data.groupby('sub_type')['sale_count'].sum().plot.pie(
    autopct='%.1f%%',
    title='各小类销售量占比',
    startangle=90
)

# 右下:小类销售额占比
plt.subplot(2, 2, 4)
data.groupby('sub_type')['销售额'].sum().plot.pie(
    autopct='%.1f%%',
    title='各小类销售额占比',
    startangle=90
)

plt.tight_layout()
plt.show()

# 打印各大类的总销售量
print("各大类销售量汇总:")
print(data.groupby('main_type')['sale_count'].sum())






#3.1.4筛选出有销量的店铺数据,并分析这些有效店铺的商品数量分布和各大类商品的总销量
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import jieba

store_sale_total = data.groupby('店名')['sale_count'].sum()
zero_sale_stores = store_sale_total[store_sale_total == 0].index.tolist()
print("总销量为0的店铺:", zero_sale_stores)  # 查看哪些店铺被排除

data1 = data[~data['店名'].isin(zero_sale_stores)].copy()

store_counts = data1['店名'].value_counts().sort_values(ascending=False)
print("\n筛选后各店铺的商品数量:")
print(store_counts)

# 4. 查看各大类的总销量
print("\n筛选后各大类的总销量:")
print(data1.groupby('main_type')['sale_count'].sum())









#3.1.5

import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np

# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

plt.figure(figsize=(16, 12))

# 上半部分:各店铺中各大类的销售量
plt.subplot(2, 1, 1)
plt.tick_params(labelsize=10)
# 用 errorbar 替代 ci 参数,消除警告
sns.barplot(
    x='店名',
    y='sale_count',
    hue='main_type',  # 按大类分组显示不同颜色
    estimator=np.sum,  # 对销量求和(而非默认的均值)
    data=data1,
    errorbar=('ci', 0)  # 替代 ci=0,不显示误差线
)
plt.title('各店铺中各大类的销售量', fontsize=20)
plt.ylabel('销量', fontsize=15)
plt.xticks(rotation=45, ha='right')  # 店名标签旋转,避免重叠

# 下半部分:各店铺中各大类的销售额
plt.subplot(2, 1, 2)
plt.tick_params(labelsize=10)
sns.barplot(
    x='店名',
    y='销售额',
    hue='main_type',
    estimator=np.sum,  # 对销售额求和
    data=data1,
    errorbar=('ci', 0)  # 不显示误差线
)
plt.title('各店铺中各大类的销售额', fontsize=20)
plt.ylabel('销售额', fontsize=15)
plt.xticks(rotation=45, ha='right')  # 店名标签旋转

plt.tight_layout()
plt.show()









#3.1.6
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np

# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

plt.figure(figsize = (16,12))

plt.subplot(2,1,1)
plt.tick_params(labelsize = 10)
sns.barplot(x = '店名', y = 'sale_count', hue = 'sub_type' ,estimator=np.sum, data = data1 , ci = 0)####estimator参数取该列的什么值
plt.title('各店铺中各小类的销售量',fontsize = 20)
plt.ylabel('销量',fontsize = 15)

plt.subplot(2,1,2)
plt.tick_params(labelsize = 10)
sns.barplot(x = '店名', y = '销售额', hue = 'sub_type' ,estimator=np.sum, data = data1 , ci = 0)
plt.title('各店铺中各小类的销售额',fontsize = 20)
plt.ylabel('销售额',fontsize = 15)
plt.tight_layout()
plt.show()




#3.1.7
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np

# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False


plt.figure(figsize = (16,12))

plt.subplot(2,1,1)
plt.tick_params(labelsize = 10)
sns.barplot(x = 'sub_type', y = 'sale_count', hue = '店名' ,estimator=np.sum, data = data1 , ci = 0)####estimator参数取该列的什么值
plt.title('各小类中各店铺的销售量',fontsize = 20)
plt.ylabel('销量',fontsize = 15)

plt.subplot(2,1,2)
plt.tick_params(labelsize = 10)
sns.barplot(x = 'sub_type', y = '销售额', hue = '店名' ,estimator=np.sum, data = data1 , ci = 0)
plt.title('各小类中各店铺的销售额',fontsize = 20)
plt.ylabel('销售额',fontsize = 15)
plt.tight_layout()
plt.show()








#性别
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
import jieba

# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False


male_keywords = ['男士', '男用', '男生', '男性', '男款']  # 男士专用关键词

def is_male_product(title):
    if not isinstance(title, str):
        return '否'  # 非字符串标题默认非男士专用
    words = jieba.lcut(title)
    for word in words:
        if word in male_keywords:
            return '是'
    return '否'

# 添加“是否男士专用”列
data['是否男士专用'] = data['title'].apply(is_male_product)

# 2. 绘制饼图
plt.figure(figsize=(16, 16))

# 左上:男士专用中小类销量占比
plt.subplot(2, 2, 1)
male_data = data.loc[data['是否男士专用'] == '是']
male_sub_sale = male_data.groupby('sub_type')['sale_count'].sum()
male_sub_sale.plot.pie(
    autopct='%.1f%%',  # 优化百分比显示
    title='男士各小类销售量占比',
    pctdistance=0.8,
    startangle=90
)

# 右上:非男士专用中小类销量占比
plt.subplot(2, 2, 2)
female_data = data.loc[data['是否男士专用'] == '否']
female_sub_sale = female_data.groupby('sub_type')['sale_count'].sum()
female_sub_sale.plot.pie(
    autopct='%.1f%%',
    title='非男士专用各小类销售量占比',
    pctdistance=0.8,
    startangle=90
)

# 左下:男士专用销量占总销量比例
plt.subplot(2, 2, 3)
total_sale_by_gender = data.groupby('是否男士专用')['sale_count'].sum()
total_sale_by_gender.plot.pie(
    autopct='%.1f%%',
    title='男士专用销售量占比',
    pctdistance=0.8,
    startangle=90
)

# 右下:男士专用销售额占总销售额比例
plt.subplot(2, 2, 4)
total_sales_by_gender = data.groupby('是否男士专用')['销售额'].sum()
total_sales_by_gender.plot.pie(
    autopct='%.1f%%',
    title='男士专用销售额占比',
    pctdistance=0.8,
    startangle=90
)

plt.tight_layout()
plt.show()

Logo

电商企业物流数字化转型必备!快递鸟 API 接口,72 小时快速完成物流系统集成。全流程实战1V1指导,营造开放的API技术生态圈。

更多推荐