Pandas数据分析实战1——淘宝粽子行业分析
淘宝粽子——可视化分析
- 1.导入模块,读取数据,分析数据,观察数据基本信息,处理缺省值
- 2.对初始数据进行进一步整理
- 3.明确需求目的
- 分析关键词:品牌、竞争度、销量、销售额、客单价、店铺数量、店铺类型
- 3.1 计算出实付金额,并根据actpay进行维度打标
- 3.2 对shop-店铺打标
- 4.开始维度分析
- 4.1 分析单个店铺销售额最高的top10
- 4.2 店铺数量Top10的总销售额
- 4.3 销量Top10 并假设大于平均销量的name来作为热门产品的最低指标
- 4.4 天猫超市分析 根据天猫超市进行关键词提取
- 4.5 五芳斋系统分析 针对shop里面的关键词提取
- 4.6 TGI指数分析 name、actpay、province、city
- 4.7 根据销量分析消费者最能接受的价格,为商家定义最合适的价格
- 4.8 根据销量分析最受欢迎的店铺
- 4.9 Top5销售额的品牌-店铺(进行分组)
- 4.10 根据actpay分析省份销售top10 可以绘制销售额省份地图分布
- 4.11 分析城市销售top10 推导城市粽子销售指数
- 4.12 每个城市店铺数量排名第一的shop
- 4.13 每个省份店铺数量排名第一的shop
- 同理我们还可以得出每个省份/城市中销售额top1的店铺/品牌
- 4.14 得到每个城市相同店铺的总销售额并排序
- 4.15 得到每个城市店铺数量排名第一的shop中的对应销售额
- 4.16 每个城市销售额top1的店铺
- 查看df,并添加brand列
- 5.可视化分析实现
- 5.1 绘制name产品名称词云图
- 6.数据源
1.导入模块,读取数据,分析数据,观察数据基本信息,处理缺省值
import pandas as pd
import numpy as np
import cufflinks as cf
import re
import os
from pyecharts.charts import *
from pyecharts import options as opts
from pyecharts.globals import ThemeType
from pyecharts.globals import SymbolType
df = pd.read_csv('zongzi.csv',header=0,names=['name','price','ppay','shop','province-city'])#产品名称,价格,付款人数,店铺,省份城市
df.head()
name | price | ppay | shop | province-city | |
---|---|---|---|---|---|
0 | 北京稻香村端午粽子手工豆沙粽220g*2袋散装豆沙粽香甜软糯豆沙粽 | 44.00 | 8人付款 | 天猫超市 | 上海 |
1 | 五芳斋粽子礼盒装鲜肉咸蛋黄大肉粽嘉兴豆沙甜粽端午团购散装礼品 | 89.90 | 100万+人付款 | 五芳斋官方旗舰店 | 浙江 嘉兴 |
2 | 稻香私房鲜肉粽蛋黄肉粽嘉兴粽子咸鸭蛋礼盒装端午节送礼特产团购 | 138.00 | 1936人付款 | 稻香村食品旗舰店 | 北京 |
3 | 嘉兴粽子 蛋黄鲜肉粽新鲜大肉粽早餐散装团购浙江特产蜜枣多口味 | 3.80 | 9500+人付款 | 城城喂食猫 | 浙江 嘉兴 |
4 | 嘉兴特产粽子礼盒装甜咸粽8粽4味真空手工农家粽端午节团购 | 58.80 | 17人付款 | chenyan30151467 | 浙江 嘉兴 |
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4402 entries, 0 to 4401
Data columns (total 5 columns):
name 4402 non-null object
price 4402 non-null float64
ppay 4331 non-null object
shop 4402 non-null object
province-city 4399 non-null object
dtypes: float64(1), object(4)
memory usage: 172.0+ KB
观察发现,付款人数、省份城市有数据缺失,原因是没有数据,其中省份城市还需要对其进行省份和城市的分离,方便TGI指数维度,并且也可以删除;付款人数缺省原因应该是0人付款或者没有,故可以删除
删除缺省值
df[df.ppay.isnull()].head()#.shape (71, 5) 一共有71行缺省
name | price | ppay | shop | province-city | |
---|---|---|---|---|---|
182 | 五芳斋 140g*8只大粽子 福韵端午豆沙蜜枣蛋黄粽新包装送礼礼盒 | 50.90 | NaN | 天猫会员店 | 上海 |
242 | 五芳斋福雅五芳粽子礼盒端午咸甜粽子绿豆糕咸鸭蛋送礼 | 79.90 | NaN | 天猫会员店 | 上海 |
346 | 【百草味】龙腾粽1090g 早餐大肉粽子湖州特产嘉兴粽 | 39.90 | NaN | 天猫会员店 | 上海 |
385 | 五芳斋华礼竹篮礼盒1360g蛋粽组合端午礼品嘉兴粽子礼盒 | 129.00 | NaN | 天猫会员店 | 上海 |
388 | 百草味 龙腾粽礼盒1460g 10只装早餐大肉粽子湖州特产嘉兴 | 49.90 | NaN | 天猫会员店 | 上海 |
#删除NaN值
df.dropna(inplace=True)#.info()
#进一步删除0人付款
df = df[~df.ppay.isin(['0人付款'])]
df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 4322 entries, 0 to 4401
Data columns (total 5 columns):
name 4322 non-null object
price 4322 non-null float64
ppay 4322 non-null object
shop 4322 non-null object
province-city 4322 non-null object
dtypes: float64(1), object(4)
memory usage: 202.6+ KB
2.对初始数据进行进一步整理
df.head()
name | price | ppay | shop | province-city | |
---|---|---|---|---|---|
0 | 北京稻香村端午粽子手工豆沙粽220g*2袋散装豆沙粽香甜软糯豆沙粽 | 44.00 | 8人付款 | 天猫超市 | 上海 |
1 | 五芳斋粽子礼盒装鲜肉咸蛋黄大肉粽嘉兴豆沙甜粽端午团购散装礼品 | 89.90 | 100万+人付款 | 五芳斋官方旗舰店 | 浙江 嘉兴 |
2 | 稻香私房鲜肉粽蛋黄肉粽嘉兴粽子咸鸭蛋礼盒装端午节送礼特产团购 | 138.00 | 1936人付款 | 稻香村食品旗舰店 | 北京 |
3 | 嘉兴粽子 蛋黄鲜肉粽新鲜大肉粽早餐散装团购浙江特产蜜枣多口味 | 3.80 | 9500+人付款 | 城城喂食猫 | 浙江 嘉兴 |
4 | 嘉兴特产粽子礼盒装甜咸粽8粽4味真空手工农家粽端午节团购 | 58.80 | 17人付款 | chenyan30151467 | 浙江 嘉兴 |
df.ppay.dtype#字符串类型
dtype('O')
#对ppay进行str处理 突然忘记re表达式了
df.ppay = df.ppay.str.replace('人付款','')
df.ppay = df.ppay.str.replace('+','')
def get_w(x):
if '万' in str(x):#这里注意,x要写成str(x),因为x里面含有float类型的数据
return (float(x[:-1])*10000)
else:
return float(x)
df['ppay'] = df.ppay.apply(get_w)
df.head()
#2
# get_w = []
# for x in list(df.ppay):
# if '万' in str(x):
# x = float(x.replace('万',''))
# get_w.append(x*10000)
# else:
# get_w.append(float(x))
# df.ppay = get_w
# df.head()
#3
# df.ppay = [(float(x.replace('万',''))*10000) if '万' in str(x) else float(x) for x in list(df.ppay)]
# df.head()
name | price | ppay | shop | province-city | |
---|---|---|---|---|---|
0 | 北京稻香村端午粽子手工豆沙粽220g*2袋散装豆沙粽香甜软糯豆沙粽 | 44.00 | 8.00 | 天猫超市 | 上海 |
1 | 五芳斋粽子礼盒装鲜肉咸蛋黄大肉粽嘉兴豆沙甜粽端午团购散装礼品 | 89.90 | 1000000.00 | 五芳斋官方旗舰店 | 浙江 嘉兴 |
2 | 稻香私房鲜肉粽蛋黄肉粽嘉兴粽子咸鸭蛋礼盒装端午节送礼特产团购 | 138.00 | 1936.00 | 稻香村食品旗舰店 | 北京 |
3 | 嘉兴粽子 蛋黄鲜肉粽新鲜大肉粽早餐散装团购浙江特产蜜枣多口味 | 3.80 | 9500.00 | 城城喂食猫 | 浙江 嘉兴 |
4 | 嘉兴特产粽子礼盒装甜咸粽8粽4味真空手工农家粽端午节团购 | 58.80 | 17.00 | chenyan30151467 | 浙江 嘉兴 |
df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 4322 entries, 0 to 4401
Data columns (total 5 columns):
name 4322 non-null object
price 4322 non-null float64
ppay 4322 non-null float64
shop 4322 non-null object
province-city 4322 non-null object
dtypes: float64(2), object(3)
memory usage: 202.6+ KB
df['ppay'] = df['ppay'].astype(int)
df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 4322 entries, 0 to 4401
Data columns (total 5 columns):
name 4322 non-null object
price 4322 non-null float64
ppay 4322 non-null int32
shop 4322 non-null object
province-city 4322 non-null object
dtypes: float64(1), int32(1), object(3)
memory usage: 185.7+ KB
df.head()
name | price | ppay | shop | province-city | |
---|---|---|---|---|---|
0 | 北京稻香村端午粽子手工豆沙粽220g*2袋散装豆沙粽香甜软糯豆沙粽 | 44.00 | 8 | 天猫超市 | 上海 |
1 | 五芳斋粽子礼盒装鲜肉咸蛋黄大肉粽嘉兴豆沙甜粽端午团购散装礼品 | 89.90 | 1000000 | 五芳斋官方旗舰店 | 浙江 嘉兴 |
2 | 稻香私房鲜肉粽蛋黄肉粽嘉兴粽子咸鸭蛋礼盒装端午节送礼特产团购 | 138.00 | 1936 | 稻香村食品旗舰店 | 北京 |
3 | 嘉兴粽子 蛋黄鲜肉粽新鲜大肉粽早餐散装团购浙江特产蜜枣多口味 | 3.80 | 9500 | 城城喂食猫 | 浙江 嘉兴 |
4 | 嘉兴特产粽子礼盒装甜咸粽8粽4味真空手工农家粽端午节团购 | 58.80 | 17 | chenyan30151467 | 浙江 嘉兴 |
#构建字典,分离省份和城市
# re_pc = {
# '上海':'上海 上海',
# '北京':'北京 北京',
# '天津':'天津 天津',
# '重庆':'重庆 重庆'
# }
# df['province-city'] = df['province-city'].str.strip().map(re_pc)
# df.head()#发现,我们需要的数据却变成了NaN,所以这种方法不行
def get_s(x):
if x == '上海':
return '上海 上海'
elif x == '北京':
return '北京 北京'
elif x == '天津':
return '天津 天津'
elif x == '重庆':
return '重庆 重庆'
else:
return x
df['province-city'] = df['province-city'].str.strip().apply(get_s)
df.head()
name | price | ppay | shop | province-city | |
---|---|---|---|---|---|
0 | 北京稻香村端午粽子手工豆沙粽220g*2袋散装豆沙粽香甜软糯豆沙粽 | 44.00 | 8 | 天猫超市 | 上海 上海 |
1 | 五芳斋粽子礼盒装鲜肉咸蛋黄大肉粽嘉兴豆沙甜粽端午团购散装礼品 | 89.90 | 1000000 | 五芳斋官方旗舰店 | 浙江 嘉兴 |
2 | 稻香私房鲜肉粽蛋黄肉粽嘉兴粽子咸鸭蛋礼盒装端午节送礼特产团购 | 138.00 | 1936 | 稻香村食品旗舰店 | 北京 北京 |
3 | 嘉兴粽子 蛋黄鲜肉粽新鲜大肉粽早餐散装团购浙江特产蜜枣多口味 | 3.80 | 9500 | 城城喂食猫 | 浙江 嘉兴 |
4 | 嘉兴特产粽子礼盒装甜咸粽8粽4味真空手工农家粽端午节团购 | 58.80 | 17 | chenyan30151467 | 浙江 嘉兴 |
df['province'] = [i[:2] for i in df['province-city']]
df['city'] = [i[3:5] for i in df['province-city']]
del df['province-city']
df.head()
name | price | ppay | shop | province | city | |
---|---|---|---|---|---|---|
0 | 北京稻香村端午粽子手工豆沙粽220g*2袋散装豆沙粽香甜软糯豆沙粽 | 44.00 | 8 | 天猫超市 | 上海 | 上海 |
1 | 五芳斋粽子礼盒装鲜肉咸蛋黄大肉粽嘉兴豆沙甜粽端午团购散装礼品 | 89.90 | 1000000 | 五芳斋官方旗舰店 | 浙江 | 嘉兴 |
2 | 稻香私房鲜肉粽蛋黄肉粽嘉兴粽子咸鸭蛋礼盒装端午节送礼特产团购 | 138.00 | 1936 | 稻香村食品旗舰店 | 北京 | 北京 |
3 | 嘉兴粽子 蛋黄鲜肉粽新鲜大肉粽早餐散装团购浙江特产蜜枣多口味 | 3.80 | 9500 | 城城喂食猫 | 浙江 | 嘉兴 |
4 | 嘉兴特产粽子礼盒装甜咸粽8粽4味真空手工农家粽端午节团购 | 58.80 | 17 | chenyan30151467 | 浙江 | 嘉兴 |
df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 4322 entries, 0 to 4401
Data columns (total 6 columns):
name 4322 non-null object
price 4322 non-null float64
ppay 4322 non-null int32
shop 4322 non-null object
province 4322 non-null object
city 4322 non-null object
dtypes: float64(1), int32(1), object(4)
memory usage: 219.5+ KB
3.明确需求目的
- 需要计算出实付金额 实付金额 actpay = price x ppay
- 对店铺shop,产品名称name进行分组
- TGI指数:假设 actpay > 某标准值 可分为维度 高客单、低客单;同时需要对客单总数kdtotal进行筛选 假设<mean(kdtotal)的行需要删除
- 初步观察,可以发现ppay是数据的核心,即销量
对ppay销量进行分析:可以与name进行分析,分析哪个品牌的产品更受欢迎;可以与price,分析消费者能够接受的价格,
对比平均价格;可以与shop,分析哪家店铺最受欢迎;
统计省份的实付金额actpay,可以分析省份消费top10;统计店铺的actpay,可以分析店铺top,并得出top10这些是那个省
和城市的,进而进一步分析;统计城市,可以分析城市消费top10;以及将三者有机结合
- name词云图关键词,看看产品名称如何定义最能吸引消费者,产品热词
- 分析shop和城市的关系,看看每个城市店铺数量排名第一的shop是?同时每个省份店铺数量排名第一的shop是?
- 对shop进行打标,分析旗舰店、会员店、专卖店/专营店、其他店铺,公司,超市这五类 进行actpay维度分析以及店铺数量分析
- 先写这些吧!
分析关键词:品牌、竞争度、销量、销售额、客单价、店铺数量、店铺类型
3.1 计算出实付金额,并根据actpay进行维度打标
df['actpay'] = df.price * df.ppay
df.head()
name | price | ppay | shop | province | city | actpay | |
---|---|---|---|---|---|---|---|
0 | 北京稻香村端午粽子手工豆沙粽220g*2袋散装豆沙粽香甜软糯豆沙粽 | 44.00 | 8 | 天猫超市 | 上海 | 上海 | 352.00 |
1 | 五芳斋粽子礼盒装鲜肉咸蛋黄大肉粽嘉兴豆沙甜粽端午团购散装礼品 | 89.90 | 1000000 | 五芳斋官方旗舰店 | 浙江 | 嘉兴 | 89900000.00 |
2 | 稻香私房鲜肉粽蛋黄肉粽嘉兴粽子咸鸭蛋礼盒装端午节送礼特产团购 | 138.00 | 1936 | 稻香村食品旗舰店 | 北京 | 北京 | 267168.00 |
3 | 嘉兴粽子 蛋黄鲜肉粽新鲜大肉粽早餐散装团购浙江特产蜜枣多口味 | 3.80 | 9500 | 城城喂食猫 | 浙江 | 嘉兴 | 36100.00 |
4 | 嘉兴特产粽子礼盒装甜咸粽8粽4味真空手工农家粽端午节团购 | 58.80 | 17 | chenyan30151467 | 浙江 | 嘉兴 | 999.60 |
df.actpay.describe()
count 4322.00
mean 71217.61
std 1549754.60
min 12.90
25% 1593.33
50% 4307.00
75% 14919.45
max 89900000.00
Name: actpay, dtype: float64
df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 4322 entries, 0 to 4401
Data columns (total 7 columns):
name 4322 non-null object
price 4322 non-null float64
ppay 4322 non-null int32
shop 4322 non-null object
province 4322 non-null object
city 4322 non-null object
actpay 4322 non-null float64
dtypes: float64(2), int32(1), object(4)
memory usage: 253.2+ KB
p_d = (df.actpay.max()-df.actpay.min())/df.shape[0]
p_d#假设p_d是我们需要的客单类别的标准值
20800.552313743636
df[df.actpay>7000].shape[0]
1674
df.ppay.max()
1000000
df.ppay.min()
1
现在有个问题,我们不知道我们这是一天的actpay,还是一个月。因为没有时间date,而且最高付款人数达到100万,最低付款人数1,如果是一天,那就太流弊了。那我们假设算作一周的销售额
并且我们假设在这里将标准值设为7000
#对客单类别进行添加
# df['kdkind'] = ['高客单' if i>7000 else '低客单' for i in df.actpay]
# df.head()
3.2 对shop-店铺打标
def get_db(x):
if '旗舰店' in str(x):
return '旗舰店'
elif '会员店' in str(x):
return '会员店'
elif '专卖店' or '专营店' in str(x):
return '专卖店/专营店'
elif '公司' or '超市' in str(x):
return '公司/超市'
else:
return '普通店铺'
df['shopkind'] = df.shop.apply(get_db)
df.head()
name | price | ppay | shop | province | city | actpay | shopkind | |
---|---|---|---|---|---|---|---|---|
0 | 北京稻香村端午粽子手工豆沙粽220g*2袋散装豆沙粽香甜软糯豆沙粽 | 44.00 | 8 | 天猫超市 | 上海 | 上海 | 352.00 | 专卖店/专营店 |
1 | 五芳斋粽子礼盒装鲜肉咸蛋黄大肉粽嘉兴豆沙甜粽端午团购散装礼品 | 89.90 | 1000000 | 五芳斋官方旗舰店 | 浙江 | 嘉兴 | 89900000.00 | 旗舰店 |
2 | 稻香私房鲜肉粽蛋黄肉粽嘉兴粽子咸鸭蛋礼盒装端午节送礼特产团购 | 138.00 | 1936 | 稻香村食品旗舰店 | 北京 | 北京 | 267168.00 | 旗舰店 |
3 | 嘉兴粽子 蛋黄鲜肉粽新鲜大肉粽早餐散装团购浙江特产蜜枣多口味 | 3.80 | 9500 | 城城喂食猫 | 浙江 | 嘉兴 | 36100.00 | 专卖店/专营店 |
4 | 嘉兴特产粽子礼盒装甜咸粽8粽4味真空手工农家粽端午节团购 | 58.80 | 17 | chenyan30151467 | 浙江 | 嘉兴 | 999.60 | 专卖店/专营店 |
4.开始维度分析
4.1 分析单个店铺销售额最高的top10
df_actpay_top10 = df.sort_values('actpay',ascending=False).head(10).reset_index()
df_actpay_top10
index | name | price | ppay | shop | province | city | actpay | shopkind | |
---|---|---|---|---|---|---|---|---|---|
0 | 1 | 五芳斋粽子礼盒装鲜肉咸蛋黄大肉粽嘉兴豆沙甜粽端午团购散装礼品 | 89.90 | 1000000 | 五芳斋官方旗舰店 | 浙江 | 嘉兴 | 89900000.00 | 旗舰店 |
1 | 13 | 真真老老嘉兴粽子礼盒装肉粽糯米鲜肉蛋黄肉大粽子甜粽端午节礼品 | 59.90 | 700000 | 真真老老旗舰店 | 浙江 | 嘉兴 | 41930000.00 | 旗舰店 |
2 | 61 | 五芳斋粽子礼盒蛋黄肉粽豆沙粽大肉棕子浙江特产新鲜嘉兴粽子肉粽 | 89.90 | 200000 | 五芳斋官方旗舰店 | 浙江 | 嘉兴 | 17980000.00 | 旗舰店 |
3 | 115 | 稻香私房嘉兴大蛋黄鲜肉粽甜味蜜枣散装粽子礼盒装端午节特产送礼 | 59.90 | 100000 | 稻香村食品旗舰店 | 北京 | 北京 | 5990000.00 | 旗舰店 |
4 | 195 | 真真老老嘉兴粽子蛋黄肉粽端午粽子礼盒装鲜肉粽子甜粽大粽子团购 | 29.90 | 200000 | 真真老老旗舰店 | 浙江 | 嘉兴 | 5980000.00 | 旗舰店 |
5 | 803 | 五芳斋粽子礼盒蛋黄肉粽端午节送礼团购肉粽豆沙棕子嘉兴特产粽子 | 89.90 | 65000 | 五芳斋官方旗舰店 | 浙江 | 嘉兴 | 5843500.00 | 旗舰店 |
6 | 25 | 知味观端午节粽子甜粽咸蛋黄大肉粽礼盒装嘉兴味鲜肉粽子散装团购 | 64.90 | 85000 | 知味观官方旗舰店 | 浙江 | 杭州 | 5516500.00 | 旗舰店 |
7 | 35 | 五芳斋粽子礼盒装新鲜大肉粽蛋黄猪肉粽豆沙端午食品团购嘉兴特产 | 39.90 | 100000 | 五芳斋浙江专卖店 | 浙江 | 嘉兴 | 3990000.00 | 专卖店/专营店 |
8 | 84 | 荃盛粽子鲜肉粽蛋黄鲜肉粽豆沙粽子甜粽端午节礼品嘉兴粽子礼盒装 | 59.90 | 65000 | 荃盛旗舰店 | 浙江 | 宁波 | 3893500.00 | 旗舰店 |
9 | 10 | 五芳斋粽子竹篮礼盒华礼嘉兴特产蛋黄鲜肉粽豆沙咸蛋端午送礼团购 | 159.00 | 20000 | 五芳斋官方旗舰店 | 浙江 | 嘉兴 | 3180000.00 | 旗舰店 |
df.price.mean()
74.28209625173452
df.price.max()
1780.0
通过上述数据,我们可以得出
- 单个店铺最高销售额TOP1是1000000元,所属店铺是五芳斋官方旗舰店,省份是浙江,城市是嘉兴,是旗舰店,产品是五芳斋粽子礼盒装鲜肉咸蛋黄大肉粽嘉兴豆沙甜粽端午团购散装礼品;
- 并且top10里面有9家浙江、8家嘉兴、9个旗舰店,5家是属于同一个品牌:五芳斋官方旗舰店。因此我们可以初步得出:
旗舰店的竞争优势在粽子行业中是很大的,并且五芳斋官方旗舰店销量可观,价格分布在中、低端,价格,品牌优势明显,可以猜测这是一家综合性的主打中端价格市场的、公司在浙江嘉兴的企业 - 提出疑问:为何浙江、嘉兴能够这么流弊?
但是细细一看,top10同一家店铺有5个,这在海量的数据中并不能很科学的表明什么,因此我们需要对shop进行分组来进一步分析
4.2 店铺数量Top10的总销售额
#对店铺进行分组,得出店铺数量top10
df_shop = df.groupby('shop')['ppay'].count().reset_index()#
df_shop.columns = ['shop','counts']
df_shop.sort_values('counts',ascending=False).head(10)
shop | counts | |
---|---|---|
599 | 天猫超市 | 270 |
363 | 五芳斋官方旗舰店 | 105 |
1066 | 稻香村食品旗舰店 | 51 |
1031 | 知味观官方旗舰店 | 47 |
1225 | 诸老大旗舰店 | 41 |
364 | 五芳斋浙江专卖店 | 38 |
1025 | 真真老老旗舰店 | 37 |
1103 | 红船旗舰店 | 30 |
927 | 润之禧旗舰店 | 28 |
1198 | 蓝氏钟楼旗舰店 | 25 |
df_shop_top = df_shop.sort_values('counts',ascending=False).head(10)
df_shop_top['counts'].head(10).mean()
67.2
从上面可以分析出:天猫超市的店铺数量为270,是top2五芳斋官方旗舰店的2倍多,这表明还是平台老板家的店铺更流弊;
其次总体旗舰店>50的只有前top3,并且高于平均值的只有前top2;
同时发现了一个问题:五芳斋既有旗舰店,还有专卖店,但是特殊问题特殊分析,我们只需要对五芳斋进行单独分析即可,或者最多前top5
#现在我们还想要把actpay列给添加上去 得到top10数量店铺的总销售额 有些店铺并不都是在一个省份、城市,所以省份、城市暂时不添加:
shop_pay_sum = df.groupby('shop')['actpay'].sum().reset_index()#
shop_pay_sum.columns = ['shop','shop_pay_sum']
shop_pay_sum = shop_pay_sum.sort_values('shop_pay_sum',ascending=False)#这里并没有对shop进行count,所以无法对shop进行排序
#进行横向合并
df_shop_sp = df_shop_top.merge(shop_pay_sum,on='shop',how='left')
#如何取消float值的科学计数法呢?
pd.set_option('display.float_format', lambda x: '%.2f' % x)
df_shop_sp.sort_values('shop_pay_sum',ascending=False).head(10)
shop | counts | shop_pay_sum | |
---|---|---|---|
1 | 五芳斋官方旗舰店 | 105 | 132389350.80 |
6 | 真真老老旗舰店 | 37 | 49396443.40 |
3 | 知味观官方旗舰店 | 47 | 9383796.92 |
0 | 天猫超市 | 270 | 8032811.77 |
2 | 稻香村食品旗舰店 | 51 | 7756471.90 |
5 | 五芳斋浙江专卖店 | 38 | 7139386.50 |
7 | 红船旗舰店 | 30 | 3154040.60 |
4 | 诸老大旗舰店 | 41 | 2757103.90 |
8 | 润之禧旗舰店 | 28 | 1783302.40 |
9 | 蓝氏钟楼旗舰店 | 25 | 274088.70 |
df_shop_sp['shop_money_avg'] = df_shop_sp['shop_pay_sum']/df_shop_sp['counts']
df_shop_sp.sort_values('shop_pay_sum',ascending=False).head(10)
shop | counts | shop_pay_sum | shop_money_avg | |
---|---|---|---|---|
1 | 五芳斋官方旗舰店 | 105 | 132389350.80 | 1260850.96 |
6 | 真真老老旗舰店 | 37 | 49396443.40 | 1335039.01 |
3 | 知味观官方旗舰店 | 47 | 9383796.92 | 199655.25 |
0 | 天猫超市 | 270 | 8032811.77 | 29751.15 |
2 | 稻香村食品旗舰店 | 51 | 7756471.90 | 152087.68 |
5 | 五芳斋浙江专卖店 | 38 | 7139386.50 | 187878.59 |
7 | 红船旗舰店 | 30 | 3154040.60 | 105134.69 |
4 | 诸老大旗舰店 | 41 | 2757103.90 | 67246.44 |
8 | 润之禧旗舰店 | 28 | 1783302.40 | 63689.37 |
9 | 蓝氏钟楼旗舰店 | 25 | 274088.70 | 10963.55 |
综合数据表明:
五芳斋官方旗舰店还是最流弊的,总销售额是考量一个企业的核心,同时top2的平均单位店铺销售额超过了top1,说明top2的竞争能力不容小觑;
天猫shop_pay_num排在了top4,但平均单位店铺销售额倒数第二,表现出在粽子行业还是专业性企业更具优势,看来天猫的店铺战效果虽可以,但是成本也很高;
同时还应该继续优化shop关键词,可重点突出top5的品牌
4.3 销量Top10 并假设大于平均销量的name来作为热门产品的最低指标
df.ppay.mean()
1298.209393799167
df_xl = df.sort_values('ppay',ascending=False)
df_xl.head(10)
name | price | ppay | shop | province | city | actpay | shopkind | |
---|---|---|---|---|---|---|---|---|
1 | 五芳斋粽子礼盒装鲜肉咸蛋黄大肉粽嘉兴豆沙甜粽端午团购散装礼品 | 89.90 | 1000000 | 五芳斋官方旗舰店 | 浙江 | 嘉兴 | 89900000.00 | 旗舰店 |
13 | 真真老老嘉兴粽子礼盒装肉粽糯米鲜肉蛋黄肉大粽子甜粽端午节礼品 | 59.90 | 700000 | 真真老老旗舰店 | 浙江 | 嘉兴 | 41930000.00 | 旗舰店 |
195 | 真真老老嘉兴粽子蛋黄肉粽端午粽子礼盒装鲜肉粽子甜粽大粽子团购 | 29.90 | 200000 | 真真老老旗舰店 | 浙江 | 嘉兴 | 5980000.00 | 旗舰店 |
61 | 五芳斋粽子礼盒蛋黄肉粽豆沙粽大肉棕子浙江特产新鲜嘉兴粽子肉粽 | 89.90 | 200000 | 五芳斋官方旗舰店 | 浙江 | 嘉兴 | 17980000.00 | 旗舰店 |
35 | 五芳斋粽子礼盒装新鲜大肉粽蛋黄猪肉粽豆沙端午食品团购嘉兴特产 | 39.90 | 100000 | 五芳斋浙江专卖店 | 浙江 | 嘉兴 | 3990000.00 | 专卖店/专营店 |
115 | 稻香私房嘉兴大蛋黄鲜肉粽甜味蜜枣散装粽子礼盒装端午节特产送礼 | 59.90 | 100000 | 稻香村食品旗舰店 | 北京 | 北京 | 5990000.00 | 旗舰店 |
25 | 知味观端午节粽子甜粽咸蛋黄大肉粽礼盒装嘉兴味鲜肉粽子散装团购 | 64.90 | 85000 | 知味观官方旗舰店 | 浙江 | 杭州 | 5516500.00 | 旗舰店 |
281 | 粽叶粽子叶粽粑叶免邮新鲜干大号竹叶包粽子的叶子棕叶竹子芦苇叶 | 3.80 | 70000 | ws10110 | 山东 | 枣庄 | 266000.00 | 专卖店/专营店 |
1755 | 真真老老 130g*1真空肉粽 嘉兴粽子 端午特产特色美食食品 | 4.80 | 70000 | 天猫超市 | 上海 | 上海 | 336000.00 | 专卖店/专营店 |
803 | 五芳斋粽子礼盒蛋黄肉粽端午节送礼团购肉粽豆沙棕子嘉兴特产粽子 | 89.90 | 65000 | 五芳斋官方旗舰店 | 浙江 | 嘉兴 | 5843500.00 | 旗舰店 |
可以发现,top5的产品在整个粽子行业有着很大的竞争优势,top5的产品最受欢迎,并且品牌效应很明显,top5都在浙江嘉兴,这说明在浙江嘉兴就是粽子行业的风口。
联系地理知识,地方产业的专业化和集中化在浙江嘉兴展露的淋漓尽致;
提出一个猜测:天猫超市销售的产品大都数都是这些专业企业所提供的?并且五芳斋的产品热度、品牌知名度非其他产业所能企及,所以我们可以对天猫超市和五芳斋进行进一步的分析;
4.4 天猫超市分析 根据天猫超市进行关键词提取
略
4.5 五芳斋系统分析 针对shop里面的关键词提取
略
4.6 TGI指数分析 name、actpay、province、city
df.shape[0]
4322
df.groupby('name')['actpay'].mean().shape[0]
4126
实际上需要的是买家昵称,但是我们只有产品昵称
上面表明还是有重复的产品昵称,我们将某一产品的平均销售额与客单标准值进行比较,这说明上面我们没有考虑重复的name,所以需要进一步的优化
df['actpay_sum'] = df.groupby('name')['actpay'].transform('mean')#将求平均销售额的分组重复展开,将name作为判断条件
# df.shape[0]3依旧是4322行,实际我们需要的还是4126行
df.head(5)
name | price | ppay | shop | province | city | actpay | shopkind | actpay_sum | |
---|---|---|---|---|---|---|---|---|---|
0 | 北京稻香村端午粽子手工豆沙粽220g*2袋散装豆沙粽香甜软糯豆沙粽 | 44.00 | 8 | 天猫超市 | 上海 | 上海 | 352.00 | 专卖店/专营店 | 352.00 |
1 | 五芳斋粽子礼盒装鲜肉咸蛋黄大肉粽嘉兴豆沙甜粽端午团购散装礼品 | 89.90 | 1000000 | 五芳斋官方旗舰店 | 浙江 | 嘉兴 | 89900000.00 | 旗舰店 | 89900000.00 |
2 | 稻香私房鲜肉粽蛋黄肉粽嘉兴粽子咸鸭蛋礼盒装端午节送礼特产团购 | 138.00 | 1936 | 稻香村食品旗舰店 | 北京 | 北京 | 267168.00 | 旗舰店 | 267168.00 |
3 | 嘉兴粽子 蛋黄鲜肉粽新鲜大肉粽早餐散装团购浙江特产蜜枣多口味 | 3.80 | 9500 | 城城喂食猫 | 浙江 | 嘉兴 | 36100.00 | 专卖店/专营店 | 18799.70 |
4 | 嘉兴特产粽子礼盒装甜咸粽8粽4味真空手工农家粽端午节团购 | 58.80 | 17 | chenyan30151467 | 浙江 | 嘉兴 | 999.60 | 专卖店/专营店 | 999.60 |
#删去重复name,但先判断provinde,city是否一致,
df[df.name=='嘉兴粽子 蛋黄鲜肉粽新鲜大肉粽早餐散装团购浙江特产蜜枣多口味']
name | price | ppay | shop | province | city | actpay | shopkind | actpay_sum | |
---|---|---|---|---|---|---|---|---|---|
3 | 嘉兴粽子 蛋黄鲜肉粽新鲜大肉粽早餐散装团购浙江特产蜜枣多口味 | 3.80 | 9500 | 城城喂食猫 | 浙江 | 嘉兴 | 36100.00 | 专卖店/专营店 | 18799.70 |
3850 | 嘉兴粽子 蛋黄鲜肉粽新鲜大肉粽早餐散装团购浙江特产蜜枣多口味 | 23.80 | 63 | 城城喂食猫 | 浙江 | 嘉兴 | 1499.40 | 专卖店/专营店 | 18799.70 |
df1 = df.drop_duplicates(subset=['name','province','city'])
df1.shape[0]#4146-4126=20,还存在20个重复值,但可以忽略不计,以这三个条件来作为标准,但是会与平均销售额所不匹配
4146
基本可以忽略不计,所以可以直接按照name删除
df_kd = df.drop_duplicates(subset=['name'])
# df_kd.shape[0]
df_kd= df_kd[['name','province','city']]
df_kd.shape
(4126, 3)
df_act = df.groupby('name',as_index=False)['actpay'].mean()
df_act.columns = ['name','act_num']
df_act.shape
(4126, 2)
df_act.head()
name | act_num | |
---|---|---|
0 | 100g10只棕子嘉兴特产五芳斋端午节新鲜肉粽子 量贩装美味鲜猪肉 | 2227.50 |
1 | 100g16个嘉禾斋匠心手造粽子豆沙梅干菜肉紫米肉粽蛋黄粽原味蜜 | 299.50 |
2 | 10个X250g熊家粽子礼盒装 贵州特产 贞丰粽子 熊家鲜肉板栗灰粽粑 | 3754.40 |
3 | 10个伍荣昌粽子海南定安黑猪肉蛋黄粽子新旧包装随机发货 | 8272.00 |
4 | 10个贵州特产兴义贞丰余家粽粑板栗鲜肉粽农家手工大灰粽子礼盒装 | 5846.40 |
#添加客单类别
# df_act['kdkind'] = ['高客单' if i>7000 else '低客单' for i in df_act.act_num]#过高,修改一波
# df_act['kdkind'] = ['高客单' if i>5000 else '低客单' for i in df_act.act_num]#不够优化
df_act['kdkind'] = ['高客单' if i>4000 else '低客单' for i in df_act.act_num]
df_act = df_act[['name','kdkind']]
df_kd = df_kd.merge(df_act,on='name',how='inner')
df_kd.head()
name | province | city | kdkind | |
---|---|---|---|---|
0 | 北京稻香村端午粽子手工豆沙粽220g*2袋散装豆沙粽香甜软糯豆沙粽 | 上海 | 上海 | 低客单 |
1 | 五芳斋粽子礼盒装鲜肉咸蛋黄大肉粽嘉兴豆沙甜粽端午团购散装礼品 | 浙江 | 嘉兴 | 高客单 |
2 | 稻香私房鲜肉粽蛋黄肉粽嘉兴粽子咸鸭蛋礼盒装端午节送礼特产团购 | 北京 | 北京 | 高客单 |
3 | 嘉兴粽子 蛋黄鲜肉粽新鲜大肉粽早餐散装团购浙江特产蜜枣多口味 | 浙江 | 嘉兴 | 高客单 |
4 | 嘉兴特产粽子礼盒装甜咸粽8粽4味真空手工农家粽端午节团购 | 浙江 | 嘉兴 | 低客单 |
df_kd.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 4126 entries, 0 to 4125
Data columns (total 4 columns):
name 4126 non-null object
province 4126 non-null object
city 4126 non-null object
kdkind 4126 non-null object
dtypes: object(4)
memory usage: 161.2+ KB
# df_result = pd.pivot_table(df_kd,index=['province','city'],columns=['kdkind'],aggfunc='count')
# df_result
df_result = df_kd.groupby(['province','city'])['kdkind'].value_counts().unstack()
df_result.info()
<class 'pandas.core.frame.DataFrame'>
MultiIndex: 164 entries, (上海, 上海) to (黑龙, 大)
Data columns (total 2 columns):
低客单 147 non-null float64
高客单 132 non-null float64
dtypes: float64(2)
memory usage: 4.7+ KB
#删除NaN值
df_result.dropna(inplace=True)
df_result.sort_values('高客单',ascending=False).head(10)
kdkind | 低客单 | 高客单 | |
---|---|---|---|
province | city | ||
浙江 | 嘉兴 | 475.00 | 584.00 |
上海 | 上海 | 240.00 | 284.00 |
北京 | 北京 | 133.00 | 188.00 |
浙江 | 杭州 | 71.00 | 103.00 |
四川 | 成都 | 69.00 | 91.00 |
广东 | 广州 | 44.00 | 50.00 |
肇庆 | 48.00 | 47.00 | |
河南 | 郑州 | 32.00 | 45.00 |
浙江 | 湖州 | 26.00 | 38.00 |
广东 | 东莞 | 32.00 | 34.00 |
这里初步估计:我们给定的标准值7000过高,浙江的高客单都低于低客单。故修改成5000,
tgi = df_result
tgi['kd_total'] = (df_result.高客单+df_result.低客单)
tgi['unit_mix'] = df_result.高客单/tgi['kd_total']#每个城市的单位占比
tgi['total_mix'] = df_result.高客单.sum()/(df_result.高客单.sum()+df_result.低客单.sum())
tgi['final_mix'] = tgi['unit_mix']/tgi['total_mix']*100
tgi.sort_values('final_mix',ascending=False).head(10)
kdkind | 低客单 | 高客单 | kd_total | unit_mix | total_mix | final_mix | |
---|---|---|---|---|---|---|---|
province | city | ||||||
江西 | 宜春 | 1.00 | 6.00 | 7.00 | 0.86 | 0.53 | 162.33 |
山东 | 枣庄 | 3.00 | 15.00 | 18.00 | 0.83 | 0.53 | 157.82 |
湖北 | 荆州 | 1.00 | 4.00 | 5.00 | 0.80 | 0.53 | 151.51 |
广东 | 梅州 | 1.00 | 3.00 | 4.00 | 0.75 | 0.53 | 142.04 |
山西 | 晋中 | 1.00 | 3.00 | 4.00 | 0.75 | 0.53 | 142.04 |
大同 | 1.00 | 3.00 | 4.00 | 0.75 | 0.53 | 142.04 | |
四川 | 乐山 | 1.00 | 3.00 | 4.00 | 0.75 | 0.53 | 142.04 |
河南 | 漯河 | 1.00 | 3.00 | 4.00 | 0.75 | 0.53 | 142.04 |
浙江 | 温州 | 10.00 | 28.00 | 38.00 | 0.74 | 0.53 | 139.55 |
河南 | 新乡 | 2.00 | 5.00 | 7.00 | 0.71 | 0.53 | 135.27 |
发现我们一直期待的浙江呢?所以我们还需要将客单总数<平均值的行进行作为无效数据处理
tgi = tgi.loc[tgi['kd_total']>tgi['kd_total'].mean()]
tgi.sort_values('final_mix',ascending=False).head(10)
kdkind | 低客单 | 高客单 | kd_total | unit_mix | total_mix | final_mix | |
---|---|---|---|---|---|---|---|
province | city | ||||||
浙江 | 温州 | 10.00 | 28.00 | 38.00 | 0.74 | 0.53 | 139.55 |
金华 | 15.00 | 28.00 | 43.00 | 0.65 | 0.53 | 123.32 | |
福建 | 泉州 | 14.00 | 25.00 | 39.00 | 0.64 | 0.53 | 121.40 |
浙江 | 宁波 | 18.00 | 32.00 | 50.00 | 0.64 | 0.53 | 121.21 |
福建 | 厦门 | 19.00 | 29.00 | 48.00 | 0.60 | 0.53 | 114.42 |
浙江 | 湖州 | 26.00 | 38.00 | 64.00 | 0.59 | 0.53 | 112.45 |
杭州 | 71.00 | 103.00 | 174.00 | 0.59 | 0.53 | 112.11 | |
北京 | 北京 | 133.00 | 188.00 | 321.00 | 0.59 | 0.53 | 110.92 |
河南 | 郑州 | 32.00 | 45.00 | 77.00 | 0.58 | 0.53 | 110.68 |
四川 | 成都 | 69.00 | 91.00 | 160.00 | 0.57 | 0.53 | 107.71 |
以为结束了,但是猛的发现我的浙江嘉兴呢?上海呢?所以感觉还不够优化 这里我们直接定义高客单要大于mean才行,或者继续优化标准值
#先重命名一下:
tgi.rename(columns={ '高客单':'hight_kd', '低客单':'lower_kd'}, inplace=True)
tgi = tgi.loc[tgi['hight_kd']>tgi['hight_kd'].mean()]
tgi.sort_values('final_mix',ascending=False)#.head(10)
kdkind | lower_kd | hight_kd | kd_total | unit_mix | total_mix | final_mix | |
---|---|---|---|---|---|---|---|
province | city | ||||||
浙江 | 杭州 | 71.00 | 103.00 | 174.00 | 0.59 | 0.53 | 112.11 |
北京 | 北京 | 133.00 | 188.00 | 321.00 | 0.59 | 0.53 | 110.92 |
四川 | 成都 | 69.00 | 91.00 | 160.00 | 0.57 | 0.53 | 107.71 |
浙江 | 嘉兴 | 475.00 | 584.00 | 1059.00 | 0.55 | 0.53 | 104.44 |
上海 | 上海 | 240.00 | 284.00 | 524.00 | 0.54 | 0.53 | 102.64 |
当我们把标准客单类别值定义为5000时,浙江嘉兴的高客单虽然很多,但是低客单十分接近高客单,所以我们应该还是不够优化!这里我们计算一下平均ppay x 平均price
当我们把标准客单类别值定义为4000时,感觉还比较可以接受,能够客观反映一些事实。因此,高客单的城市主要是杭州、北京、成都、嘉兴、上海;综合比较嘉兴、北京、上海的消费潜力最大,竞争能力也最强劲
(df.actpay.max()-df.ppay.mean()*df.price.mean())/(df.ppay.mean()*df.price.mean()-df.actpay.min())
931.3711582889754
(df.actpay.max()-df.actpay.mean())/(df.actpay.mean()-df.actpay.min())
1261.5567232220394
因此估计理论客单类别标准值为13002000最为合适,但是实际上一周2000得到一天300,感觉过低;一天500差不多了,35004000比较合适
4.7 根据销量分析消费者最能接受的价格,为商家定义最合适的价格
#先统计价格
df_p = df.groupby('price',as_index=False)['ppay'].count()
df_p.columns = ['price','counts']
df_p.sort_values('counts',ascending=False).head()
price | counts | |
---|---|---|
248 | 39.90 | 150 |
328 | 59.90 | 126 |
293 | 49.90 | 111 |
182 | 29.90 | 104 |
362 | 69.90 | 89 |
df_p1 = df.groupby('price',as_index=False)['ppay'].mean()
#得到统计top5的价格对应的平均销量,以此来作为最优价格的依据
df_p = df_p.merge(df_p1,on='price',how='left')
df_p['ppay'] = df_p['ppay'].astype(int)
df_p.sort_values('counts',ascending=False).head()
price | counts | ppay | |
---|---|---|---|
248 | 39.90 | 150 | 2511 |
328 | 59.90 | 126 | 7399 |
293 | 49.90 | 111 | 879 |
182 | 29.90 | 104 | 2860 |
362 | 69.90 | 89 | 776 |
df.price.mean()
74.28209625173452
df.price.max()
1780.0
df_p_max = df[['price','ppay','actpay']].sort_values('actpay',ascending=False).reset_index()
df_p_max[df_p_max.price==1780]
index | price | ppay | actpay | |
---|---|---|---|---|
866 | 2797 | 1780.00 | 12 | 21360.00 |
df_p_max[df_p_max.actpay>100000].tail(1)
index | price | ppay | actpay | |
---|---|---|---|---|
253 | 2038 | 11.80 | 8500 | 100300.00 |
price.max()为1780,ppay为12,actpay排行在866,算是比较靠前,但该actpay与10万的排名相差600多,销售额并不是很华丽。初步估计这家店铺以品牌策略为核心,吸引高端消费者,但是间接反映粽子行业的高端化还不足以让大部分消费者为之接受买单;
商家的价格分布主要是在中低端,对top5价格进行mean(),初步估计商家预估市场最优价格为50/49.9;进一步分析得知:price为59.9的时候,平均销量远多于top2的2860(当然这里我们还需要对ppay进行int处理,因为付款人数不能是浮点数,这不符合常理);
综合比较,最优price为59.9元,也是消费者最能接受并反馈效果nice的价格,对于商家而言也有利可图
4.8 根据销量分析最受欢迎的店铺
df.ppay.max()
1000000
df[['name','ppay','shop','price']].sort_values('ppay',ascending=False).head()
name | ppay | shop | price | |
---|---|---|---|---|
1 | 五芳斋粽子礼盒装鲜肉咸蛋黄大肉粽嘉兴豆沙甜粽端午团购散装礼品 | 1000000 | 五芳斋官方旗舰店 | 89.90 |
13 | 真真老老嘉兴粽子礼盒装肉粽糯米鲜肉蛋黄肉大粽子甜粽端午节礼品 | 700000 | 真真老老旗舰店 | 59.90 |
195 | 真真老老嘉兴粽子蛋黄肉粽端午粽子礼盒装鲜肉粽子甜粽大粽子团购 | 200000 | 真真老老旗舰店 | 29.90 |
61 | 五芳斋粽子礼盒蛋黄肉粽豆沙粽大肉棕子浙江特产新鲜嘉兴粽子肉粽 | 200000 | 五芳斋官方旗舰店 | 89.90 |
35 | 五芳斋粽子礼盒装新鲜大肉粽蛋黄猪肉粽豆沙端午食品团购嘉兴特产 | 100000 | 五芳斋浙江专卖店 | 39.90 |
这个前面写过了,ppay.max()是100万,据此最受欢迎、热度最高的单个店铺是销售五芳斋粽子礼盒装鲜肉咸蛋黄大肉粽嘉兴豆沙甜粽端午团购散装礼品的五芳斋官方旗舰店,隶属于品牌五芳斋;
试想一下:为什么top1店铺五芳斋的的销量可以远超top2店铺真真老老,这个可以自行百度了解其两家企业的背景的销售策略;
并且在众多同品牌的旗舰店里,为何这两家可以脱颖而出,也值得思考;
再添加价格发现,两家店铺的策略核心并非是价格战,据此推测,品牌知名度和口碑、质量才是关键
4.9 Top5销售额的品牌-店铺(进行分组)
#df.shop.size == df.shop.count()
#前面我们已经分析了单个店铺销售额的TOP10,但是存在同一家品牌有多家店铺的情况,所以我们需要对其进行关键词打标,但是品牌基本有1000多家,所以我们只取销售额前5的品牌,并且就等价于df_shop_sp
df_b = df.groupby('shop')['actpay'].sum().reset_index()
df_b.columns = ['shop','actpay_sum']
df_b = df_b.sort_values('actpay_sum',ascending=False)
df_b.head(6)
# df_shop_sp.sort_values('shop_pay_sum',ascending=False).head(6)
shop | actpay_sum | |
---|---|---|
363 | 五芳斋官方旗舰店 | 132389350.80 |
1025 | 真真老老旗舰店 | 49396443.40 |
1031 | 知味观官方旗舰店 | 9383796.92 |
599 | 天猫超市 | 8032811.77 |
1066 | 稻香村食品旗舰店 | 7756471.90 |
364 | 五芳斋浙江专卖店 | 7139386.50 |
#对shop关键词打标
def get_brand(x):
if '五芳斋' in str(x):
return '五芳斋'
elif '真真老老' in str(x):
return '真真老老'
elif '知味观' in str(x):
return '知味观'
elif '天猫' in str(x):
return '天猫'
elif '稻香村' in str(x):
return '稻香村'
else:
return '其他品牌'
df_b['brand'] = df_b.shop.apply(get_brand)
df_b.shape[0]
1396
df_b.groupby('brand')['actpay_sum'].sum().reset_index().sort_values('actpay_sum',ascending=False)
brand | actpay_sum | |
---|---|---|
0 | 五芳斋 | 142594195.10 |
1 | 其他品牌 | 89070190.17 |
3 | 真真老老 | 49520183.20 |
4 | 知味观 | 9527274.62 |
5 | 稻香村 | 9057861.60 |
2 | 天猫 | 8032811.77 |
这里我们可以知晓五芳斋这个品牌的总销售额,以及top5品牌的总销售额
4.10 根据actpay分析省份销售top10 可以绘制销售额省份地图分布
df_province = df.groupby('province')['actpay'].sum().reset_index()
df_province.columns = ['province','actpay_sum']
df_province.sort_values('actpay_sum',ascending=False).head(10)
province | actpay_sum | |
---|---|---|
18 | 浙江 | 247933130.02 |
3 | 北京 | 13535824.88 |
0 | 上海 | 13265888.79 |
11 | 广东 | 5600816.91 |
14 | 江苏 | 3328178.93 |
17 | 河南 | 2898866.22 |
5 | 四川 | 2661052.99 |
9 | 山东 | 2593401.82 |
16 | 河北 | 2360518.78 |
12 | 广西 | 2345014.19 |
浙江消费总和约是北京的18倍,这足以证明浙江省是粽子行业的龙头,而北京、上海依据自身城市优势,粽子行业有了一定的集群化规模。这里有个疑问:北京、上海的粽子行业中,对应的销售额top5品牌占有多少的比重?
df[(df.province=='北京') & (df['shop'].str.contains('五芳斋'))]
name | price | ppay | shop | province | city | actpay | shopkind | actpay_sum |
---|
???,没有?有点不可思议,继续试试
s_top3 = ['浙江','北京','上海']
[df[(df.province== i)].shape[0] for i in s_top3]#df[(df.province== '浙江') & (df['shop'].str.contains('五芳斋'))]
[1567, 327, 541]
#五芳斋 真真老老 知味观 稻香村 天猫
ps_top5 = ['五芳斋','真真老老','知味观','天猫超市','稻香村']#这里将销售额top5品牌进行关键词处理
df_pstop_count = [df[(df.province=='北京') & (df['shop'].str.contains(i))].shape[0] for i in ps_top5]#在北京的销售额top5品牌店铺数量分布
df_pstop_count
[0, 0, 0, 0, 79]
[df[(df.province=='上海') & (df['shop'].str.contains(i))].shape[0] for i in ps_top5]
[0, 0, 0, 269, 0]
[df[(df.province=='浙江') & (df['shop'].str.contains(i))].shape[0] for i in ps_top5]
[187, 49, 60, 0, 0]
shop_mix = df_b.iloc[:3,1].sum()/(df_province['actpay_sum'].max())
shop_mix
0.7710530299221361
Top5店铺 五芳斋 真真老老 知味观 稻香村 天猫
这里可以得知:
top3省份或直辖市中,北京以稻香村这一品牌店铺为主导,占北京所有店铺327家的24%;
天猫超市几乎全部坐落在上海,占比接近50%;
浙江突出top3品牌店铺,累计接近300家,占浙江总店铺数1567的19%,但三家品牌的全国总销售额占整个浙江的77%,再结合前面的店铺数量以及省份分布,可以得出这三家都是浙江本土品牌,并占据主导地位
4.11 分析城市销售top10 推导城市粽子销售指数
#我们先进行城市店铺分布数量统计
df_city_c = df.groupby('city')['actpay'].count().reset_index().sort_values('actpay',ascending=False)
df_city_c.columns = ['city','counts']
df_city_c.head(10)
city | counts | |
---|---|---|
37 | 嘉兴 | 1144 |
6 | 上海 | 541 |
23 | 北京 | 327 |
77 | 杭州 | 180 |
64 | 成都 | 175 |
55 | 广州 | 99 |
126 | 肇庆 | 96 |
144 | 郑州 | 77 |
71 | 无锡 | 76 |
8 | 东莞 | 68 |
结合上面的浙江1567,浙江嘉兴就占了1144家,这更加证实了嘉兴不愧是粽子之乡,以及嘉兴粽子行业的专业化、集群化
df_c_act = df.groupby('city')['actpay'].sum().reset_index().sort_values('actpay',ascending=False)
df_c_act.columns = ['city','actpay_sum']
#合并
df_city_top = df_city_c.merge(df_c_act,on='city',how='left')
df_city_top.head(10)
city | counts | actpay_sum | |
---|---|---|---|
0 | 嘉兴 | 1144 | 225036692.48 |
1 | 上海 | 541 | 13265888.79 |
2 | 北京 | 327 | 13535824.88 |
3 | 杭州 | 180 | 12041022.94 |
4 | 成都 | 175 | 2418058.71 |
5 | 广州 | 99 | 2441452.28 |
6 | 肇庆 | 96 | 1146536.80 |
7 | 郑州 | 77 | 2462143.10 |
8 | 无锡 | 76 | 714951.07 |
9 | 东莞 | 68 | 756769.05 |
df_city_top.actpay_sum.max()/df_province.actpay_sum.max()
0.9076507543055946
嘉兴的总销售额占浙江总销售额的90%,这就很离谱哦!,北京、上海也没有让我们失望,其他城市大都是省份的省府,但综合比较还是杭州最强。
个人推测:粽子行业的销售额呈现从浙江嘉兴为中心的向四周辐射、从高到低的局面
4.12 每个城市店铺数量排名第一的shop
#利用groupby来实现第一步
# df_c_max = df.groupby(['city','shop'],as_index=False)['actpay'].count()
# df_c_max= df_c_max.sort_values('actpay',ascending=False)
# df_c_max = df_c_max.drop_duplicates(subset='city')#利用去重保存first
# # df_c_max.shape[0]
# df_c_max.rename(columns={'actpay':'c_s_counts'}, inplace=True)
# df_c_max.head()
df_c_max = pd.pivot_table(df,index=['city','shop'],aggfunc='count')
df_c_max = df_c_max[['actpay']]
df_c_max = df_c_max.sort_values('actpay',ascending=False).reset_index()
df_c_max = df_c_max.drop_duplicates(subset='city')#利用去重保存first
# df_c_max.shape[0]
df_c_max.rename(columns={ 'actpay':'c_s_counts'}, inplace=True)
df_c_max.head()
city | shop | c_s_counts | |
---|---|---|---|
0 | 上海 | 天猫超市 | 269 |
1 | 嘉兴 | 五芳斋官方旗舰店 | 105 |
2 | 北京 | 稻香村食品旗舰店 | 51 |
3 | 杭州 | 知味观官方旗舰店 | 47 |
9 | 泉州 | 蓝氏钟楼旗舰店 | 25 |
# df_c_max[df_c_max['city']=='黔西']
从中可以分析出,在每个城市中的主导店铺、品牌
4.13 每个省份店铺数量排名第一的shop
df_p_max = pd.pivot_table(df,index=['province','shop'],aggfunc='count')
df_p_max = df_p_max[['actpay']]
df_p_max = df_p_max.sort_values('actpay',ascending=False).reset_index()
df_p_max = df_p_max.drop_duplicates(subset='province')#利用去重保存first
# df_p_max.shape[0]
df_p_max.rename(columns={ 'actpay':'c_s_counts'}, inplace=True)
df_p_max.head()
province | shop | c_s_counts | |
---|---|---|---|
0 | 上海 | 天猫超市 | 269 |
1 | 浙江 | 五芳斋官方旗舰店 | 105 |
2 | 北京 | 稻香村食品旗舰店 | 51 |
9 | 福建 | 蓝氏钟楼旗舰店 | 25 |
10 | 河北 | 三全京之良品专卖店 | 23 |
从中可以分析出,在每个省份中的主导店铺、品牌
同理我们还可以得出每个省份/城市中销售额top1的店铺/品牌
4.14 得到每个城市相同店铺的总销售额并排序
df_c_pay_max = df.groupby(['city','shop'],as_index=False)['actpay'].sum().sort_values('actpay',ascending=False)
df_c_pay_max.head()
4.15 得到每个城市店铺数量排名第一的shop中的对应销售额
df_c_pay_max = df.groupby(['city','shop'],as_index=False)['actpay'].sum().sort_values('actpay',ascending=False)#得到每个城市相同店铺的总销售额并排序
#这里不需要删除去重,因为我们只需要得到每个城市的相同店铺销售额即可
df_c_pay_max = df_c_pay_max.merge(df_c_max,on=['city','shop'],how='right')#以df_c_max表为主进行连接,得到其对应的销售额
df_c_pay_max.head()
4.16 每个城市销售额top1的店铺
df_c_pay = df.groupby(['city','shop'],as_index=False)['actpay'].sum().sort_values('actpay',ascending=False)
df_c_pay = df_c_pay.drop_duplicates(subset='city')#删除相同城市中店铺销售额不是第一的行
df_c_pay.rename(columns={ 'actpay':'actpay_sum'}, inplace=True)
df_c_pay.head()
查看df,并添加brand列
#为df添加brand列
df['brand'] = df.shop.apply(get_brand)
df.sort_values('actpay',ascending=False).head(20)
name | price | ppay | shop | province | city | actpay | shopkind | actpay_sum | brand | |
---|---|---|---|---|---|---|---|---|---|---|
1 | 五芳斋粽子礼盒装鲜肉咸蛋黄大肉粽嘉兴豆沙甜粽端午团购散装礼品 | 89.90 | 1000000 | 五芳斋官方旗舰店 | 浙江 | 嘉兴 | 89900000.00 | 旗舰店 | 89900000.00 | 五芳斋 |
13 | 真真老老嘉兴粽子礼盒装肉粽糯米鲜肉蛋黄肉大粽子甜粽端午节礼品 | 59.90 | 700000 | 真真老老旗舰店 | 浙江 | 嘉兴 | 41930000.00 | 旗舰店 | 20967174.55 | 真真老老 |
61 | 五芳斋粽子礼盒蛋黄肉粽豆沙粽大肉棕子浙江特产新鲜嘉兴粽子肉粽 | 89.90 | 200000 | 五芳斋官方旗舰店 | 浙江 | 嘉兴 | 17980000.00 | 旗舰店 | 17980000.00 | 五芳斋 |
115 | 稻香私房嘉兴大蛋黄鲜肉粽甜味蜜枣散装粽子礼盒装端午节特产送礼 | 59.90 | 100000 | 稻香村食品旗舰店 | 北京 | 北京 | 5990000.00 | 旗舰店 | 5990000.00 | 稻香村 |
195 | 真真老老嘉兴粽子蛋黄肉粽端午粽子礼盒装鲜肉粽子甜粽大粽子团购 | 29.90 | 200000 | 真真老老旗舰店 | 浙江 | 嘉兴 | 5980000.00 | 旗舰店 | 5980000.00 | 真真老老 |
803 | 五芳斋粽子礼盒蛋黄肉粽端午节送礼团购肉粽豆沙棕子嘉兴特产粽子 | 89.90 | 65000 | 五芳斋官方旗舰店 | 浙江 | 嘉兴 | 5843500.00 | 旗舰店 | 5843500.00 | 五芳斋 |
25 | 知味观端午节粽子甜粽咸蛋黄大肉粽礼盒装嘉兴味鲜肉粽子散装团购 | 64.90 | 85000 | 知味观官方旗舰店 | 浙江 | 杭州 | 5516500.00 | 旗舰店 | 5516500.00 | 知味观 |
35 | 五芳斋粽子礼盒装新鲜大肉粽蛋黄猪肉粽豆沙端午食品团购嘉兴特产 | 39.90 | 100000 | 五芳斋浙江专卖店 | 浙江 | 嘉兴 | 3990000.00 | 专卖店/专营店 | 3990000.00 | 五芳斋 |
84 | 荃盛粽子鲜肉粽蛋黄鲜肉粽豆沙粽子甜粽端午节礼品嘉兴粽子礼盒装 | 59.90 | 65000 | 荃盛旗舰店 | 浙江 | 宁波 | 3893500.00 | 旗舰店 | 3893500.00 | 其他品牌 |
10 | 五芳斋粽子竹篮礼盒华礼嘉兴特产蛋黄鲜肉粽豆沙咸蛋端午送礼团购 | 159.00 | 20000 | 五芳斋官方旗舰店 | 浙江 | 嘉兴 | 3180000.00 | 旗舰店 | 3180000.00 | 五芳斋 |
40 | 鲜肉粽嘉兴粽子蛋黄肉粽咸散装端午节大甜粽送礼品团购批发礼盒装 | 39.90 | 55000 | 集采食品专营店 | 浙江 | 嘉兴 | 2194500.00 | 专卖店/专营店 | 2194500.00 | 其他品牌 |
793 | 嘉兴粽子新鲜大肉粽蛋黄肉粽甜粽竹篮粽子礼盒装组合端午送礼团购 | 857.90 | 2491 | 千味食代i | 浙江 | 嘉兴 | 2137028.90 | 专卖店/专营店 | 2137028.90 | 其他品牌 |
130 | 【百亿补贴】五芳斋新鲜粽子礼盒装大肉粽豆沙嘉兴端午送礼咸鸭蛋 | 99.90 | 20000 | 五芳斋浙江专卖店 | 浙江 | 嘉兴 | 1998000.00 | 专卖店/专营店 | 1998000.00 | 五芳斋 |
113 | 五芳斋蛋黄肉粽量贩装 嘉兴特产大粽子肉粽子团购礼品早餐鲜肉粽 | 95.00 | 20000 | 五芳斋官方旗舰店 | 浙江 | 嘉兴 | 1900000.00 | 旗舰店 | 333003.33 | 五芳斋 |
1174 | 五芳斋粽子蛋黄肉粽豆沙棕子多口味组合 端午节浙江特产嘉兴粽子 | 34.90 | 50000 | 五芳斋官方旗舰店 | 浙江 | 嘉兴 | 1745000.00 | 旗舰店 | 1745000.00 | 五芳斋 |
175 | 怀裕泰 粽子礼盒装 嘉兴棕子蛋黄鲜肉粽端午节送礼礼品大团购定制 | 39.90 | 40000 | 怀裕泰旗舰店 | 浙江 | 嘉兴 | 1596000.00 | 旗舰店 | 1596000.00 | 其他品牌 |
75 | 三全粽子礼盒装肉粽嘉兴粽子豆沙蜜枣粽端午甜粽散装特产鲜肉粽叶 | 49.90 | 30000 | 三全京之良品专卖店 | 河北 | 廊坊 | 1497000.00 | 专卖店/专营店 | 1497000.00 | 其他品牌 |
1332 | 五芳斋x太极禅苑粽子礼盒 嘉兴特产粽子蛋黄肉粽蜜枣粽端午节礼品 | 149.00 | 10000 | 五芳斋官方旗舰店 | 浙江 | 嘉兴 | 1490000.00 | 旗舰店 | 1490000.00 | 五芳斋 |
114 | 五芳斋福享五芳粽子礼盒端午节大蛋黄肉粽豆沙甜棕子特产嘉兴粽子 | 89.90 | 15000 | 五芳斋官方旗舰店 | 浙江 | 嘉兴 | 1348500.00 | 旗舰店 | 675674.00 | 五芳斋 |
76 | 德荣恒竹篮粽子礼盒装蛋黄鲜肉粽散装大甜粽端午节嘉兴特产送礼品 | 27.80 | 45000 | 德荣恒旗舰店 | 浙江 | 嘉兴 | 1251000.00 | 旗舰店 | 1251000.00 | 其他品牌 |
5.可视化分析实现
未完待续
5.1 绘制name产品名称词云图
6.数据源
点击此处
链接:https://pan.baidu.com/s/1N\_DVRlfJQElZT\_0oP\_7gtQ
提取码:love
复制这段内容后打开百度网盘手机App,操作更方便哦
个人学习成果检验,学习笔记而已,望大佬给出宝贵意见。觉得有帮助,就请给我一个鼓励的赞
还没有评论,来说两句吧...