電商打折套路分析 —— Python數據分析練習

 

電商打折套路分析

——2016天貓雙十一美妝數據分析html

數據簡介

  • 這次分析的數據來自於城市數據團對2016年雙11天貓數據的採集和整理,原始數據爲.xlsx格式
  • 包括update_time/id/title/price/店名,共5個字段,其中id爲商品的惟一標識,店名爲品牌名。

分析工具

  • 主要使用了Python中的Pandas庫進行數據處理,利用matplotlib繪製分析圖表,利用bokeh進行了可視化展現。數組

  • 當前使用版本:Python 3.6.5 |Anaconda, Inc.| (default, Mar 29 2018, 13:32:41) [MSC v.1900 64 bit (AMD64)]app

說明

  • 本次數據分析主要供學習使用,目的在於熟悉Python及相關庫,同時練習數據分析的思惟方式。
  • 本次分析主要基於描述性統計,暫不包含預測模型。
  • 文字說明會涉及實現的具體細節,而不只是分析結果的展現。
  • bokeh製圖爲交互式圖表,此處截圖展現
  • 數據每日只採集一次,對於一日以內的變化沒法進行分析

分析目標

  • 商品銷售時間分析
    1. 統計出商品總數和品牌總數
    2. 計算雙十一當天在售商品佔比
    3. 未參與雙十一當天活動的商品,雙十一以後的去向
    4. 參加雙十一活動的品牌及其商品數量的分佈
  • 價格折扣分析
    1. 針對每一個商品,分析其價格變化,判斷是否打折
    2. 針對在打折商品,計算其折扣率
    3. 按照品牌分析,不一樣品牌的打折力度
    4. 分析商家打折套路
  • 構建商品id/品牌的彙總表
    1. 商品id資料表格
    2. 品牌彙總資料表格
    3. 假打折商品詳情

正文

相關模塊導入

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
% matplotlib inline
import seaborn as sns

import warnings
warnings.filterwarnings('ignore') 
# 不發出警告

from bokeh.io import output_notebook
output_notebook()
# 導入notebook繪圖模塊
from bokeh.plotting import figure,show
from bokeh.models import ColumnDataSource
# 導入圖表繪製、圖標展現模塊
# 導入ColumnDataSource模塊

import os

 

加載數據和數據預處理

  • 設置工做路徑,pandas導入數據
  • 檢查數據是否有缺失值
  • 檢查數據類型
  • 對數據進行基本預處理
  • 查看數據
# 加載數據
data = pd.read_excel('雙十一淘寶美妝數據.xlsx')

data[data.isnull().values == True].drop_duplicates
# 檢查缺失值
data.dtypes
# 查看數據類型

data.index = data['update_time']
data['date'] = data.index.day
# Series沒有.day方法,利用index作了一步轉換

data = data.drop('update_time', axis = 1)
data.reset_index(inplace = True)
data.rename(columns = {'店名': 'brand'}, inplace = True)

data.head()

Part1 商品銷售時間分析

  1. 統計出商品總數和品牌總數
  2. 計算雙十一當天在售商品佔比
  3. 未參與雙十一當天活動的商品,雙十一以後的去向
  4. 參加雙十一活動的品牌及其商品數量的分佈

統計商品總數和品牌總數ssh

data1 = data[['id','title', 'brand', 'price', 'date']]

items_num = len(data1['id'].unique())
brands_num = len(data1['brand'].unique())

print('商品總數爲: %d' %items_num)
print('品牌總數爲: %d' %brands_num)

獲得商品總數:3502,品牌總數:22函數

計算雙十一當天在售商品佔比工具

items_at11 = data1[data1['date'] == 11].drop_duplicates()
items_at11_num = len(items_at11)
precentage_11 = items_at11_num / items_num

print('雙十一當天在售商品佔比爲: %.2f%%' %(precentage_11 * 100))

獲得雙十一當天在售商品佔比爲:66.68%,約1/3的商品在雙十一當天沒有上架學習

 

商品銷售狀況分類

爲了分析沒參加雙十一的產品去向,咱們首先對全部商品id依據其上架時間進行分類。
根據date字段,統計每件商品的最先和最遲銷售時間;再統計雙11當天是否銷售;最後進行分類。spa

    • A. 11.11先後及當天都在售 → 一直在售
    • B. 11.11以後中止銷售 → 雙十一後中止銷售
    • C. 11.11開始銷售並當天不中止 → 雙十一當天上架並持續在售
    • D. 11.11開始銷售且當天中止 → 僅雙十一當天有售
    • E. 11.5 - 11.9 → 雙十一前中止銷售
    • F. 僅11.11當天中止銷售 → 僅雙十一當天中止銷售
    • G. 11.12開始銷售 → 雙十一後上架
    • H. 11.10下架 → 可能11.11售罄 之後單獨分析
# 分析商品最先/最遲銷售時間,及雙11當天銷售狀況
data_sellrange = data1.groupby('id')['date'].agg(['min', 'max'])
id_at11 = data1[data1['date'] == 11]['id']

data_temp1 = pd.DataFrame({'id': id_at11, 'on11sale': True})

data1_id = pd.merge(data_sellrange, data_temp1, left_index = True, right_on = 'id', how = 'left')
data1_id.fillna(False, inplace = True)
data1_id['type'] = 'unclassified'
data1_id = data1_id.reset_index()
data1_id = data1_id.drop('index', 1)

data1_id.head()

# 分類
data1_id = data1_id.reset_index()
data1_id = data1_id.drop('index', 1)

data1_id['type'][(data1_id['min'] < 11) & (data1_id['max'] > 11)] = 'A'
data1_id['type'][(data1_id['min'] < 11) & (data1_id['max'] == 11)] = 'B'
data1_id['type'][(data1_id['min'] == 11) & (data1_id['max'] > 11)] = 'C'
data1_id['type'][(data1_id['min'] == 11) & (data1_id['max'] == 11)] = 'D'
data1_id['type'][data1_id['on11sale'] == False] = 'F'
# 此時的F還包括E/H的狀況
data1_id['type'][data1_id['max'] < 10] = 'E'
data1_id['type'][data1_id['min'] > 11] = 'G'
data1_id['type'][data1_id['max'] == 10] = 'H'

data1_id[data1_id['type'] == 'unclassified']
# 檢查分類是否完備

# 分類的可視化
result1 = data1_id['type'].value_counts()
# 用於可視化的數據命名爲result
result1 = result1.loc[['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']]
# 用於調整Series中Index的順序

plt.rcParams['font.sans-serif']=['SimHei']
# 用來正常顯示中文標籤
plt.axis('equal')
# 保證長寬相等 --> 餅圖爲圓形
plt.pie(result1,labels = result1.index, autopct='%.2f%%',pctdistance=0.8,labeldistance =1.1,
        startangle=90, radius=1.5,counterclock=False)                 
# 繪製餅圖

 

未參與雙十一活動的商品去向分析

  • 暫時下架
  • 更名上架
  • 預售
  • 未參與活動
# 選擇數據字段
id_not11 = data1_id[data1_id['on11sale'] == False]
df_not11 = id_not11[['id', 'type']]
# 此時沒有title字段,須要找到data1合併
data1_not11 = pd.merge(df_not11, data1, how = 'left', on = 'id')
data1_not11.head()

# case1 暫時下架
not11_case1 = data1_not11[data1_not11['type'] == 'F']['id'].drop_duplicates()
id_case1 = not11_case1.reset_index().drop('index', 1)
id_case1['case1'] = 1
# .unique()出現numpy數組,drop_duplicates()返回Series

# case2 改名上架
not11_case2 = data1_not11.groupby(['id', 'title']).count().reset_index()
# 此時聚合的結果爲每個(id - title)對,對應的出現次數,即出現的日期和
title_count = not11_case2['id'].value_counts().reset_index()
# 計算id出現的次數,若是次數大於1,則說明商品更改過title
# reset_index() 使原來index裏的信息成爲一個新的列
id_case2 = title_count[title_count['id'] > 1][['index']]
id_case2.columns = ['id']
id_case2['case2'] = 1

# case3 預售
not11_case3 = data1_not11[data1_not11['title'].str.contains('預售')]
id_case3 = not11_case3['id'].drop_duplicates().reset_index().drop('index', 1)
# .unique() 返回ndarray / .drop_duplicates() 返回Serise
id_case3['case3'] = 1

# case4 未參與活動
not11_case4 = data1_not11[(data1_not11['type'] == 'E') | (data1_not11['type'] == 'G')]['id'].drop_duplicates()
id_case4 = not11_case4.reset_index().drop('index', 1)
id_case4['case4'] = 1

print("未參與雙十一當天活動的商品中:\n暫時下架商品的數量爲%i個,改名上架商品的數量爲\
%i個,預售商品的數量爲%i個,未參與活動商品數量爲%i個" %(len(id_case1), len(id_case2), len(id_case3), len(id_case4)))

未參與雙十一當天活動的商品中:3d

暫時下架商品的數量爲242個,改名上架商品的數量爲110個,預售商品數量爲453個,未參與活動商品數量爲200個excel

# 查看沒被分類的其餘狀況
id_not11_left = id_not11[['id', 'min', 'max', 'type']].reset_index()
id_not11_left = id_not11_left.drop('index', axis = 1)
#id_not11_left['case'] = ''
id_not11_left = pd.merge(id_not11_left, id_case1, how = 'left', on = 'id')
id_not11_left = pd.merge(id_not11_left, id_case2, how = 'left', on = 'id')
id_not11_left = pd.merge(id_not11_left, id_case3, how = 'left', on = 'id')
id_not11_left = pd.merge(id_not11_left, id_case4, how = 'left', on = 'id')
id_not11_left = id_not11_left.fillna(0)
id_not11_left['left'] = id_not11_left['case1'] + id_not11_left['case2'] + id_not11_left['case3'] + id_not11_left['case4']
id_not11_others = id_not11_left[id_not11_left['left'] == 0][['id', 'min', 'max', 'type']]

id_not11_others.head()
# 未歸入分類的商品都是10日下架的,可能於雙11當天售罄
# 暫時下架/改名上架/預售 可能互相包含

 

參加雙十一活動的品牌及其商品數量的分佈

  • 真正參與雙十一活動的商品 = 雙十一當天在售的商品 + 預售商品
  • 對暫時下架/改名上架/售罄商品 後續能夠研究其價格變化再肯定
  • 繪製堆疊圖進行可視化
id_at11 = id_at11.reset_index().drop('index', 1)
id_presell = id_case3[['id']]
id_11all = pd.concat([id_at11, id_presell], ignore_index = True)
# 篩選雙十一當日在售商品和預售商品id

id_presell['presell'] = True
id_11all['11all'] = True

data1_id = pd.merge(data1_id, id_presell, how = 'left', on = 'id')
data1_id.fillna(False, inplace = True)
data1_id = pd.merge(data1_id, id_11all, how = 'left', on = 'id')
data1_id.fillna(False, inplace = True)

data1_brand = data1[['id', 'brand']].drop_duplicates()
data1_id = pd.merge(data1_id, data1_brand, on = 'id', how = 'left')
# 合併數據 銷售狀況 id brand

data1_id.head()

data1_on11sale = data1_id[data1_id['on11sale'] == True]
brand_on11sale = data1_on11sale.groupby('brand')['id'].count()

data1_presell = data1_id[data1_id['presell'] == True]
brand_presell = data1_presell.groupby('brand')['id'].count()
# 統計各品牌雙十一當天在售和預售商品數量

# 利用bokeh繪製堆疊圖
from bokeh.models import HoverTool
from bokeh.core.properties import value

result2 = pd.DataFrame({'on11sale': brand_on11sale,
                        'presell': brand_presell})
result2['11all'] = result2['on11sale'] + result2['presell']
result2.sort_values(by = '11all', inplace = True, ascending = False)

lst_brand = result2.index.tolist()
lst_type = result2.columns.tolist()[:2]
colors = ["#718dbf" ,"#e84d60"]
# 設置好參數

result2.index.name = 'brand'
# 重命名標籤
source1 = ColumnDataSource(result2)
# 建立數據

hover1 = HoverTool(tooltips = [('品牌', '@brand'),
                               ('雙十一當天參與活動商品數量', '@on11sale'),
                               ('預售商品數量', '@presell'),
                               ('參與雙十一活動商品總數', '@11all')
                               ])
# 設置標籤顯示內容
#output_file('折扣商品數量.html')

p1 = figure(x_range = lst_brand,
            plot_width = 900, plot_height = 350,
            title = '各個品牌參與雙十一活動的商品數量分佈',
            tools = [hover1, 'reset, xwheel_zoom, pan, crosshair'])
# 構建繪圖空間

p1.vbar_stack(stackers = lst_type,
              x = 'brand', source = source1,
              width = 0.9, color = colors, alpha = 0.8,
              legend = [value(x) for x in lst_type],
              muted_color = 'black', muted_alpha = 0.2)
# 繪製堆疊圖

p1.xgrid.grid_line_color = None
p1.axis.minor_tick_line_color = None
p1.outline_line_color = None
p1.legend.location = "top_right"
p1.legend.orientation = "horizontal"
p1.legend.click_policy="mute"
# 設置其餘參數

show(p1)

補充品牌數據彙總

data1_brands = result2.copy()
brand_total_item = data1_brand.groupby('brand').count()
brand_total_item.columns = ['total_items']
data1_brands = pd.merge(data1_brands, brand_total_item, left_index = True, right_index = True, how = 'outer')

data1_brands.head()
  on11sale presell 11all total_items
brand        
SKII 40 15 55 62
佰草集 208 32 240 279
倩碧 144 49 193 211
蘭芝 107 4 111 156
蘭蔻 112 27 139 168

 

Part2 價格折扣分析

1. 針對每一個商品,分析其價格變化,判斷是否打折 2. 針對在打折商品,計算其折扣率 3. 按照品牌分析,不一樣品牌的打折力度 4. 分析商家打折套路
 

針對每一個商品,評估其打折狀況

  • 真打折:商品的價格在10天內有波動,雙11價格爲10天內最低價,無提早漲價
  • 假打折:雙十一以前存在漲價現象
  • 不打折:商品價格無變化
data2 = data[['id', 'title', 'brand', 'price', 'date']]
data2['period'] = pd.cut(data2['date'], [4, 10, 11, 14], labels = ['雙十一前', '雙十一當天', '雙十一後'])
# 篩選數據

data2_price = data2[['id', 'price', 'period']].groupby(['id', 'period']).agg(['min', 'max'])
data2_price.reset_index(inplace = True)
data2_price.columns = ['id', 'period', 'min_price', 'max_price']
# 找到每一個時段對應的最高和最低價格

data2_price_before11 = data2_price[data2_price['period'] == '雙十一前']
# 分析雙十一以前的價格變化 --> 分析屬於提早降價仍是假打折(先漲價後降價)
data2_price_before11_diff = data2_price_before11[data2_price_before11['min_price'] != data2_price_before11['max_price']].reset_index().drop('index', 1)
# 找出雙十一前價格變化的商品
diff_id = data2_price_before11_diff['id'].tolist()

data2_diffprice = pd.merge(data2, data2_price_before11_diff, on = 'id', how = 'left')
# 與原始數據合併,查看價格變化商品的具體狀況
data2_diffpriceonly = data2_diffprice.dropna()
data2_diffpriceonly.drop('period_y', 1, inplace = True)
# 刪除多餘的列和缺失值

before11_diff = data2_diffpriceonly[data2_diffpriceonly['period_x'] != '雙十一後'].reset_index().drop('index', 1)
# 只查看雙十一以前和當天的數據
before_11diffprice = before11_diff.pivot_table(index = 'id', columns = 'date', aggfunc = {'price':min})
# 數據透視表
before_11diffprice.columns = [5, 6, 7, 8, 9, 10, 11]
# 列名改用數字,不用字符串,方便運算

def function(df, *colnums):
    a = 0
    for colnum in colnums:
        if df[colnum + 1] - df[colnum] > 0.1:
            a = 1
    return a

before_11diffprice['jdz'] = before_11diffprice.apply(lambda x: function(x, 5, 6, 7, 8, 9), axis = 1)
# 選擇出漲價的商品在假打折列名標註1
# 只統計漲價1毛以上的
# DataFrame.apply函數的應用,若是設置axis參數爲1則每次函數每次會取出DataFrame的一行來作處理

jdz_num = before_11diffprice['jdz'].sum()
# 共有16件商品假打折
jdz_items = pd.merge(data1_id, before_11diffprice, on = 'id', how = 'right')
jdz_items = jdz_items[jdz_items['jdz'] == 1]
jdz_items = jdz_items[jdz_items['jdz'] == 1].reset_index().drop('index', 1)

jdz_id = jdz_items[['id', 'jdz']]
# 提取假打折商品id

jdz_items

觀察數據可知

  • 假打折商品的品牌集中於妮維雅和美加淨(各6件),美寶蓮有1件
  • 蘭蔻有一件商品在雙十一前漲價後,雙十一當日下架
  • SKII和薇姿各有一件商品漲價後,雙十一當天維持該價格
  • 大牌套路深,深知法律風險,但這四件商品依舊被劃分在假打折!
data2_nocheat = pd.merge(data2, jdz_id, on = 'id', how = 'left')
data2_nocheat['jdz'].fillna(0, inplace = True)
data2_nocheat = data2_nocheat[data2_nocheat.jdz.isin([0])]
# 根據列條件刪除行使用.isin(),參數爲列表,如選擇不包含,前面加負號
# 提取非假打折商品

price = data2_nocheat[['id', 'price', 'period']].groupby(['id', 'price']).min()
price.reset_index(inplace = True)
# 針對每一個商品作price字段的value值統計,查看價格是否有波動

id_count = price['id'].value_counts()
id_type1 = id_count[id_count == 1].index
# 價格無波動,不打折
id_type2 = id_count[id_count != 1].index
# 價格變更

n1 = len(id_type1)
n2 = len(id_type2)
print('真打折的商品數量約佔比%.2f%%,不打折的商品數量約佔比%.2f%%, 假打折的商品數量約佔比%.2f%%' % \
      (n2/items_num * 100, n1/items_num * 100, jdz_num/items_num * 100))
# 計算打折商品比例

真打折的商品約佔比24.27%,不打折的商品數量約佔比75.27%,假打折的商品約佔0.46%

針對在打折商品,計算其折扣率

  • 去除假打折商品
  • 考慮雙十一價格對比其先後的折扣率,主要考慮前折扣率
  • 只計算九五折以上折扣
result3_pivot = data2_nocheat.pivot_table(index = 'id', columns = 'period', aggfunc = {'price': min})
# 數據透視能夠一步到位,省卻無數步驟
result3_pivot.columns = ['price_before11', 'price_on11', 'price_after11']
result3_pivot = result3_pivot.reset_index()

nocheat_idbrand = data2_nocheat[['id', 'brand']].drop_duplicates()
result3_final = pd.merge(result3_pivot, nocheat_idbrand, on = 'id').reset_index().drop('index', 1)
# 與品牌名合併

result3_final['qzkl'] = result3_final['price_on11'] / result3_final['price_before11']
result3_final['hzkl'] = result3_final['price_on11'] / result3_final['price_after11']
# 計算商品的先後折扣率

result3_on11 = result3_final.dropna()
# 篩選出雙十一銷售商品的折扣率
result3_zk = result3_on11[result3_on11['qzkl'] < 0.96].reset_index()
# 篩選出真打折的商品

result3_zk.head()
  index id price_before11 price_on11 price_after11 brand qzkl hzkl
0 0 A10027317366 188.0 159.00 258.0 相宜本草 0.845745 0.616279
1 2 A10847151685 180.0 125.99 240.0 佰草集 0.699944 0.524958
2 8 A12455538031 79.0 69.00 79.0 美寶蓮 0.873418 0.873418
3 26 A12591129422 189.0 179.00 250.0 玉蘭油 0.947090 0.716000
4 35 A12620798148 238.0 219.00 260.0 玉蘭油 0.920168 0.842308

 

## 用bokeh繪製折線圖:x軸爲折扣率,y軸爲商品數量佔比
## 商品折扣率統計,每一個折扣區間與總打折商品佔比
bokeh_data = result3_zk[['id', 'qzkl']]
bokeh_data['zkl_range'] = pd.cut(bokeh_data['qzkl'], bins = np.linspace(0, 1, 21))
# 建立折扣率區間

bokeh_data2 = bokeh_data.groupby('zkl_range').count().iloc[:-1]
bokeh_data2['zkl_pre'] = bokeh_data2['qzkl'] / bokeh_data2['qzkl'].sum()
# 將數據按照折扣率拆分爲不一樣區間,並統計不一樣1扣率的商品數量

bokeh_data2 = bokeh_data2.reset_index().drop('id', axis = 1)
bokeh_data2.dtypes
# 查看bokeh_data2數據類型,zkl_range類型爲category --> str
bokeh_data2['zkl_range'] = bokeh_data2['zkl_range'].astype(str)
# bokeh_data2['zkl_range'] = list(map(str,bokeh_data2['zkl_range']))

bokeh_data2.head()

#output_file('商品折扣率統計折線圖.html')

source2 = ColumnDataSource(bokeh_data2)
lst_zkl = bokeh_data2['zkl_range'].tolist()
# 此時列表中每一個元素均爲str

hover2 = HoverTool(tooltips = [('折扣商品數量', '@qzkl')])

p2 = figure(x_range = lst_zkl,
            plot_width = 900, plot_height = 350,
            title = '商品折扣率統計',
            tools = [hover2, 'reset, xwheel_zoom, pan, crosshair'])
# 構建繪圖空間

p2.line(x = 'zkl_range', y = 'zkl_pre', source = source2,
        line_width = 2, line_alpha = 0.8, line_color = 'black', line_dash = [10, 4])

p2.circle(x = 'zkl_range', y = 'zkl_pre', source = source2,
          size = 8, color = 'red', alpha = 0.8)

p2.xgrid.grid_line_color = None
p2.axis.minor_tick_line_color = None
p2.outline_line_color = None
# 設置其餘參數
show(p2)

觀察上圖可知,商品折扣率主要集中在五折和九折,兩者共佔50%以上

根據商品id彙總數據

  • 包括商品銷售時間和價格折扣數據
result3_zk['zk'] = 1

# 根據id彙總數據
jdz_merge = jdz_items[['id', 'jdz']]
result3_zk_merge = result3_zk[['id', 'zk']]
data2_id = pd.merge(result3_final, jdz_merge, on = 'id', how = 'outer')
data2_id['jdz'].fillna(0, inplace = True)
data2_id = pd.merge(data2_id, result3_zk_merge, on = 'id', how = 'outer')
data2_id['zk'].fillna(0, inplace = True)
# 整理商品id的折扣狀況

data1_id = data1_id.drop_duplicates()
# 商品銷售狀況去重

data_id = pd.merge(data1_id, data2_id, on = 'id', how = 'outer')
data_id.drop('brand_y', axis = 1, inplace = True)
data_id.rename(columns = {'min': 'begin', 'max': 'end', 'brand_x': 'brand'}, inplace = True)
# 彙總商品id的全數據

data_id.head()

根據品牌彙總數據

  • 包括品牌商品銷售時間和價格折扣數據
  • 計算品牌折扣商品比例
brand_zk_num = result3_zk.groupby('brand')[['id']].count()
# 品牌折扣商品數
brand_jdz_num = jdz_items.groupby('brand')[['id']].count()
# 品牌假打折商品數
brand_zk_num.columns = ['zk_num']
brand_jdz_num.columns = ['jdz_num']
#重命名

brand_zkmean = result3_zk.groupby('brand')['price_before11', 'price_on11', 'price_after11', 'qzkl', 'hzkl'].mean()
brand_zkmean.columns = ['zkprice_before11', 'zkprice_on11', 'zkprice_after11', 'qzkl_mean', 'hzkl_mean']
# 品牌折扣商品價格、折扣率均值

brand_totalmean = data_id.groupby('brand')['price_before11', 'price_on11', 'price_after11'].mean()
brand_totalmean.columns = ['meanprice_before11', 'meanprice_on11', 'meanprice_after11']
# 品牌商品價格均值

data2_brands = pd.merge(brand_zk_num, brand_jdz_num, left_index = True, right_index = True, how = 'outer')
data2_brands = pd.merge(data2_brands, brand_totalmean, left_index = True, right_index = True, how = 'outer')
data2_brands.fillna(0, inplace = True)
data2_brands = pd.merge(data2_brands, brand_zkmean, left_index = True, right_index = True, how = 'outer')
# 彙總品牌價格折扣數據

data_brands = pd.merge(data1_brands, data2_brands, left_index = True, right_index = True, how = 'outer')
# 彙總品牌數據

data_brands['zk_pre'] = data_brands['zk_num'] / data_brands['total_items']
# 計算品牌折扣商品比例

data_brands

按照品牌分析,不一樣品牌的打折力度

  • 利用bokeh繪製浮動散點圖
  • y座標爲品牌名,x座標爲折扣力度
from bokeh.transform import jitter

brands = lst_brand.copy()
# 提取品牌列表

bokeh_data3 = result3_final[['id', 'qzkl', 'brand']].dropna()
bokeh_data3 = bokeh_data3[bokeh_data3['qzkl'] < 0.96]

source3 = ColumnDataSource(bokeh_data3)
# 建立數據

#output_file('不一樣品牌折扣狀況.html')

hover3 = HoverTool(tooltips = [('折扣率', '@qzkl'),
                               ('品牌', '@brand')])
# 設置標籤顯示內容

p3 = figure(y_range = brands, plot_width = 800, plot_height = 600,
            title = '不一樣品牌折扣狀況',
            tools = [hover3, 'box_select, reset, xwheel_zoom, pan, crosshair'])    

p3.circle(x = 'qzkl',
          y = jitter('brand', width = 0.7, range = p3.y_range),
          source = source3,
          alpha = 0.3)
# jitter參數 → 'day':第一參數,這裏指y的值
# width:間隔寬度比例,range:分類範圍對象,這裏和y軸的分類一致

show(p3)

 

分析商家打折套路

  • 篩選各品牌的折扣商品比例和平均折扣率
  • 劃分四個象限,利用bokeh製圖
bokeh_data4 = data_brands[['total_items', 'qzkl_mean', 'zk_pre']]
bokeh_data4['size'] = bokeh_data4['total_items'] * 0.2
bokeh_data4.columns = ['amount', 'zkl', 'pre', 'size']
bokeh_data4.reset_index(inplace = True)
# 篩選出品牌商品總數,打折商品比例,平均折扣率
# 將點的大小設置爲與商品總數有關

from bokeh.models.annotations import Span
from bokeh.models.annotations import Label
from bokeh.models.annotations import BoxAnnotation
# 導入註釋相關模塊

source4 = ColumnDataSource(bokeh_data4)
# 建立ColumnDataSource數據

#output_file('各個品牌打折套路解析.html')

x_mean = bokeh_data4['pre'].mean()
y_mean = bokeh_data4['zkl'].mean()

hover4 = HoverTool(tooltips = [('品牌','@brand'),
                              ('折扣率','@zkl'),
                              ('商品總數','@amount'),
                              ('參與打折商品比例','@pre')])
p4 = figure(plot_width = 800, plot_height = 800,
           title = '各個品牌打折套路解析',
           tools = [hover4,'box_select,reset,wheel_zoom,pan,crosshair'])
# 構建繪圖空間

p4.circle_x(x = 'pre', y = 'zkl', source = source4, size = 'size',
           fill_color = 'red', line_color = 'black', fill_alpha =0.6,
           line_dash = [8,3])
p4.ygrid.grid_line_dash = [6,4]
p4.xgrid.grid_line_dash = [6,4]

x = Span(location=x_mean, dimension='height', line_color='green',line_alpha = 0.7, line_width=1.5, line_dash = [6,4])
y = Span(location=y_mean, dimension='width', line_color='green',line_alpha = 0.7, line_width=1.5, line_dash = [6,4])
p4.add_layout(x)
p4.add_layout(y)
# 繪製輔助線

bg1 = BoxAnnotation(bottom=y_mean, right=x_mean,fill_alpha=0.1, fill_color='olive')
label1 = Label(x=0.0, y=0.60,text="少許大打折",text_font_size="10pt" )
p4.add_layout(bg1)
p4.add_layout(label1)
# 繪製第一象限

bg2 = BoxAnnotation(bottom=y_mean, left=x_mean,fill_alpha=0.1, fill_color='firebrick')
label2 = Label(x=0.35, y=0.60,text="大量大打折",text_font_size="10pt" )
p4.add_layout(bg2)
p4.add_layout(label2)
# 繪製第二象限

bg3 = BoxAnnotation(top=y_mean, right=x_mean,fill_alpha=0.1, fill_color='firebrick')
label3 = Label(x=0.0, y=0.80,text="少許少打折",text_font_size="10pt" )
p4.add_layout(bg3)
p4.add_layout(label3)
# 繪製第三象限

bg4 = BoxAnnotation(top=y_mean, left=x_mean,fill_alpha=0.1, fill_color='olive')
label4 = Label(x=0.35, y=0.80,text="大量少打折",text_font_size="10pt" )
p4.add_layout(bg4)
p4.add_layout(label4)
# 繪製第四象限

show(p4)

打折套路解析

  • 少許大打折:雅詩蘭黛、蘭蔻、薇姿、悅詩風吟、歐珀萊
  • 大量少打折:歐萊雅、玉蘭油、美寶蓮、妮維雅、蜜絲佛陀、美加淨
  • 大量大打折:天然堂、相宜本草、佰草集
  • 不打折:SKII、倩碧、蘭芝、嬌蘭、植村秀、資生堂、雅漾、雪花秀
  • 假打折現象:妮維雅和美加淨各有6件商品
 

Part3 彙總表格導出

  • 商品id資料表格
  • 品牌彙總資料表格
  • 假打折商品詳情
# 商品id資料表格
data_id_ch = data_id.copy()
data_id_ch.columns = ['最先上架', '最遲上架', '商品id', '雙十一當天售賣', '銷售時間分類',\
                      '是否預售', '預售+雙11當天', '品牌', '雙十一前價格', '雙十一當天價格',\
                      '雙十一以後價格', '前折扣率', '後折扣率', '假打折', '真打折']

data_brands_ch = data_brands.copy()
data_brands_ch.columns = ['雙十一當日商品數', '預售商品數', '雙十一商品總數', '商品總數',\
                          '真打折商品數', '假打折商品數', '雙十一前均價', '雙十一當天均價',\
                          '雙十一以後均價', '打折商品雙十一前均價', '打折商品雙十一均價',\
                          '打折商品雙十一以後均價', '平均前折扣率', '平均後折扣率',\
                          '折扣商品佔比']

jdz_items_ch = jdz_items.copy()
jdz_items_ch.columns = ['最先上架', '最遲上架', '商品id', '雙十一當天售賣', '銷售時間分類',\
                      '是否預售', '預售+雙11當天', '品牌', '5日價格', '6日價格', '7日價格',\
                      '8日價格', '9日價格', '10日價格', '11日價格', '假打折']

data_id_ch.to_excel('商品id資料表格.xlsx')
data_brands_ch.to_excel('品牌彙總資料表格.xlsx')
jdz_items_ch.to_excel('假打折商品詳情.xlsx')

data_id.to_excel('data_id.xlsx')
data_brands.to_excel('data_brands.xlsx')
jdz_items.to_excel('jdz_items.xlsx')
相關文章
相關標籤/搜索