雙十一打折套路分析
1、從現有數據中,分析出“各個品牌都有多少商品參加了雙十一活動?”
1、從現有數據中,分析出“各個品牌都有多少商品參加了雙十一活動?” ① 計算得到:商品總數、品牌總數 ② 雙十一當天在售的商品占比情況 (思考:是不是只有雙十一當天在售的商品是“參與雙十一活動的商品?”) ② 未參與雙十一當天活動的商品,在雙十一之后的去向如何? ③ 真正參與雙十一活動的品牌有哪些? 其各個品牌參與雙十一活動的商品數量分布是怎樣的? * 用bokeh繪制柱狀圖表示
---->>> ① 數據的“id”字段為商品的實際唯一標識,“title”字段則為商品在網頁上顯示的名稱 * 仔細看數據可以發現,同一個id的title不一定一樣(雙十一前后) ② 數據的“店名”字段為品牌的唯一標識 ③ 按照商品銷售節奏分類,我們可以將商品分為7類 A. 11.11前后及當天都在售 → 一直在售 B. 11.11之后停止銷售 → 雙十一后停止銷售 C. 11.11開始銷售並當天不停止 → 雙十一當天上架並持續在售 D. 11.11開始銷售且當天停止 → 僅雙十一當天有售 E. 11.5 - 11.10 → 雙十一前停止銷售 F. 僅11.11當天停止銷售 → 僅雙十一當天停止銷售 G. 11.12開始銷售 → 雙十一后上架 ④ 未參與雙十一當天活動的商品,可能有四種情況: con1 → 暫時下架(F) con2 → 重新上架(E中部分數據,數據中同一個id可能有不同title,“換個馬甲重新上架”),字符串查找特定字符 dataframe.str.contains('預售') con3 → 預售(E中部分數據,預售商品的title中包含“預售”二字) con4 → 徹底下架(E中部分數據),可忽略 ⑤ 真正參加活動的商品 = 雙十一當天在售的商品 + 預售商品 (可以嘗試結果去重) 通過上述幾個指標計算,研究出哪些是真正參與雙十一活動的品牌,且其商品數量是多
import numpy as np import pandas as pd import matplotlib.pyplot as plt import warnings warnings.filterwarnings('ignore') from bokeh.plotting import figure, show, output_file from bokeh.models import ColumnDataSource ''' (1)導入數據 ''' import os os.chdir(r'C:\\Users\\Administrator\\Desktop\\python數據分析\\項目\\08電商') df = pd.read_excel('雙十一淘寶美妝數據.xlsx', sheetname = 0) df.fillna(0, inplace = True) df.index = df['update_time'] df['date'] = df.index.day #加載數據,提取日期 ''' (2)雙十一當天在售的商品占比情況 ''' data1 = df[['id', 'title', '店名', 'date']] d1 = data1[['id', 'date']].groupby(by = 'id').agg(['min', 'max'])['date'] #每個商品銷售的第一天和最后一天的日期; #統計不同商品的銷售開始、結束日期 id_11 = data1[data1['date'] == 11]['id'] d2 = pd.DataFrame({'id':id_11, '雙十一當天是否售賣':True}) #篩選雙十一當天售賣的商品id id_date = pd.merge(d1, d2, left_index = True, right_on = 'id', how = 'left') id_date.fillna(False, inplace = True) m = len(d1) m_11 = len(id_11) m_pre = m_11 / m print('雙十一當天參與活動的商品為%i個, 占比%.2f%%' % (m_11, m_pre*100)) ''' (3)商品銷售節奏分類 ''' id_date['type'] = '待分類' id_date['type'][(id_date['min'] < 11 ) & (id_date['max'] > 11)] = 'A' id_date['type'][(id_date['min'] < 11 ) & (id_date['max'] == 11)] = 'B' id_date['type'][(id_date['min'] == 11 ) & (id_date['max'] > 11)] = 'C' id_date['type'][(id_date['min'] == 11 ) & (id_date['max'] == 11)] = 'D' id_date['type'][id_date['雙十一當天是否售賣'] == False] = 'F' id_date['type'][id_date['max'] < 11] = 'E' id_date['type'][id_date['min'] > 11] = 'G' #銷售節奏分類 result1 = id_date['type'].value_counts() result1 = result1.loc[['A', 'C','B', 'D', 'E', 'F', 'G']] #計算不同類別的商品數量 from bokeh.palettes import brewer colori = brewer['YlGn'][7] plt.axis('equal') plt.pie(result1, labels = result1.index, autopct = '%.2f%%', colors = colori, startangle = 90, radius = 1.5, counterclock = False) ''' (4)未參與雙十一當天活動的商品,去向如何 ''' id_not11 = id_date[id_date['雙十一當天是否售賣'] == False] df_not11 = id_not11[['id', 'type']] data_not11 = pd.merge(df_not11, df, on = 'id', how = 'left') #找到雙十一當天未參與活動的商品對應的原始數據 id_con1 = id_date['id'][id_date['type'] == 'F'].values #篩選出con1,雙十一暫時下架的商品 data_con2 = data_not11[['id','title','date']].groupby(by = ['id','title']).count() #做個分類,區分,分組,計數 title_count = data_con2.reset_index()['id'].value_counts() #同一個id可能有兩個名稱 #data_not11[data_not11['id'] == 'A536510937963'] 這里id有多個名稱 id_con2 = title_count[title_count > 1].index #篩選出con2,id不止一個的名稱 data_con3 = data_not11[data_not11['title'].str.contains('預售')] id_con3 = data_con3['id'].value_counts().index #篩選出con3,預售的 print('未參與雙十一當天活動的商品中:%i個為暫時下架,%i個重新上架商品,%i個為預售商品'%(len(id_con1), len(id_con2), len(id_con3))) ''' (5)真正參與雙十一活動的商品及品牌情況 真正參與雙十一活動的商品 = 雙十一當天在售的商品 + 預售商品 (可嘗試結果去重) ''' data_11sale = id_11 #雙十一當天在售的 id_11sale_final = np.hstack((data_11sale, id_con3)) #垂直豎向堆疊把他倆加起來,真正參加活動的商品 result2_i = pd.DataFrame({'id':id_11sale_final}) #把它變成dataframe #真正參與雙十一活動的商品,只得到它的id,還要得到它的品牌---->>> x1 = pd.DataFrame({'id':id_11}) x1_df = pd.merge(x1, df, on = 'id', how = 'left') #把源數據找到 brand_11sale = x1_df.groupby('店名')['id'].count() #不同品牌當天參與雙十一活動的商品數量 x2 = pd.DataFrame({'id':id_con3}) x2_df = pd.merge(x2, df, on = 'id', how = 'left') brand_ys = x2_df.groupby('店名')['id'].count() #不同品牌的預售商品數量 result2_data = pd.DataFrame({'當天參與活動的商品數量': brand_11sale, '預售商品數量':brand_ys}) result2_data['總量'] = result2_data['當天參與活動的商品數量'] + result2_data['預售商品數量'] result2_data.sort_values(by = '總量', inplace = True, ascending = False) #計算結果 from bokeh.models import HoverTool from bokeh.core.properties import value lst_brand = result2_data.index.tolist() lst_type = result2_data.columns.tolist()[: 2] colors = ['red', 'green'] #基本參數 result2_data.index.name = 'brand' result2_data.columns = ['sale_on_11', 'presell', 'sum'] source = ColumnDataSource(result2_data) hover = HoverTool(tooltips = [("品牌", "@brand"), ("雙十一當天參與活動的商品數量", "@sale_on_11"), ("預售商品數量", "@presell"), ("真正參與雙十一活動的商品總數", "@sum")]) output_file('project8_pic1.html') p = figure(x_range = lst_brand, plot_width = 900, plot_height = 350, title = '各個品牌參與雙十一活動的情況', tools = [hover, 'xwheel_zoom, pan, crosshair']) p.vbar(top = 'sum', x = 'brand', source = source, width = 0.9, #color = colors, alpha = 0.7, #legend = [value(x) for x in 1st_type] muted_color = 'black', muted_alpha = 0.2) show(p) print('finish')
2、哪些商品真的在打折呢?
2、哪些商品真的在打折呢?
① 針對每個商品,評估其打折的情況 ② 針對在打折的商品,其折扣率是多少 * 用bokeh繪制折線圖:x軸為折扣率,y軸為商品數量 ③ 按照品牌分析,不同品牌的打折力度 * 用bokeh繪制浮動散點圖,y坐標為品牌類型,x坐標為折扣力度
----->>> ① 打折情況評估方法: 真打折:商品的價格在10天內有波動、雙11價格為10天內最低價、不存在漲價現象 不打折:商品價格無變化 ② 針對每個商品做price字段的value值統計,查看價格是否有波動,可以先用pd.cut將date分為不同周期:'雙十一前','雙十一當天','雙十一后',得到period字段 data[['id','price','date']].groupby(['id','price']).min() 針對統計出來的結果,如果按照id和price分組仍只有一個唯一值,則說明價格未變,沒打折;否則為打折 ③ 折扣率 = 雙十一當天價格 / 雙十一之前價格 ④ 作圖過程中,清除掉折扣率大於95%的數據
import numpy as np import pandas as pd import matplotlib.pyplot as plt import warnings warnings.filterwarnings('ignore') from bokeh.plotting import figure, show, output_file from bokeh.models import ColumnDataSource from bokeh.models import HoverTool from bokeh.core.properties import value ''' (1)導入數據 ''' import os os.chdir(r'C:\\Users\\Administrator\\Desktop\\python數據分析\\項目\\08電商') df = pd.read_excel('雙十一淘寶美妝數據.xlsx', sheetname = 0) df.fillna(0, inplace = True) df.index = df['update_time'] df['date'] = df.index.day #加載數據,提取日期 data2 = df[['id', 'title', '店名', 'date', 'price']] data2['period'] = pd.cut(data2['date'], [4,10,11,14], labels = ['雙十一前', '雙十一當天', '雙十一后']) #篩選數據 ''' (2)針對每個商品,評估其打折的情況 ''' price = data2[['id', 'price', 'period']].groupby(['id', 'price']).min() price.reset_index(inplace = True) #查看數據是否有波動 id_count = price['id'].value_counts() id_type1 = id_count[id_count == 1].index id_type2 = id_count[id_count != 1].index #篩選出“不打折”與“打折”商品數量 ''' (3)針對在打折的商品,其折扣率是多少,並制作圖表 ''' result3_data1 = data2[['id', 'price', 'period', '店名']].groupby(['id', 'price']).min() result3_data1.reset_index(inplace = True) #篩選數據 result3_before11 = result3_data1[result3_data1['period'] == '雙十一前'] result3_at11 = result3_data1[result3_data1['period'] == '雙十一當天'] result3_data2 = pd.merge(result3_before11, result3_at11, on = 'id') #合並數據 result3_data2['zkl'] = result3_data2['price_y'] / result3_data2['price_x'] #計算折扣率 bokeh_data = result3_data2[['id', 'zkl']].dropna() bokeh_data['zkl_range'] = pd.cut(bokeh_data['zkl'], bins = np.linspace(0, 1, 21)) bokeh_data2 = bokeh_data.groupby('zkl_range').count().iloc[:-1] bokeh_data2['zkl_pre'] = bokeh_data2['zkl'] / bokeh_data2['zkl'].sum() #計算折扣區間占比 output_file('project8_pic2.html') source1 = ColumnDataSource(bokeh_data2) lst_zkl = bokeh_data2.index.tolist() hover = HoverTool(tooltips = [("折扣率", "@zkl")]) p = figure(x_range= lst_zkl, plot_width=900 ,plot_height=350, title = '商品折扣率統計', tools = [hover, 'reset, xwheel_zoom, pan, crosshair']) p.line(x = 'zkl_range', y = 'zkl_pre', source = source1, line_color = 'black',line_dash = (10,4)) p.circle(x = 'zkl_range', y = 'zkl_pre', source = source1, size = 8, color = 'red', alpha = 0.8) show(p) ''' (4)按照品牌分析,不同品牌的打折力度 ''' from bokeh.transform import jitter brands = result3_data2['店名_x'].dropna().unique().tolist() bokeh_data3 = result3_data2[['id', 'zkl', '店名_x']].dropna() bokeh_data3 = bokeh_data3[bokeh_data3['zkl'] < 0.96] source2 = ColumnDataSource(bokeh_data3) output_file('project08_pic3.html') p2 = figure(y_range = brands, plot_width = 900, plot_height = 600, title = '不同品牌的折扣情況', tools = [hover, 'box_select, reset, xwheel_zoom, pan, crosshair']) p2.circle(x = 'zkl', y = jitter('店名_x', width = 0.7, range = p2.y_range), source = source2, alpha = 0.3) show(p2) print('finish')
3、商家營銷套路挖掘?
3、商家營銷套路挖掘? ① 解析出不同品牌的參與打折商品比例及折扣力度,並做散點圖,總結打折套路 * 用bokeh繪制散點圖,x軸為參與打折商品比例,y軸為折扣力度,點的大小代表該品牌參加雙11活動的商品總數 ---->>> ① 折扣力度為該品牌所有打折商品的折扣均值,這里去掉品牌中不打折的數據 ② 繪制散點圖后,可以將x、y軸繪制均值輔助線,將繪圖空間分為四個象限,基於該象限來總結套路
import numpy as np import pandas as pd import matplotlib.pyplot as plt import warnings warnings.filterwarnings('ignore') from bokeh.plotting import figure, show, output_file from bokeh.models import ColumnDataSource from bokeh.models import HoverTool ''' (1)數據計算 ''' data_zk = result3_data2[result3_data2['zkl'] < 0.95] result4_zkld = data_zk.groupby('店名_y')['zkl'].mean() #篩選出不同品牌的折扣情況 n_dz = data_zk['店名_y'].value_counts() n_zs = result3_data2['店名_y'].value_counts() result4_dzspb1 = pd.DataFrame({'打折商品數': n_dz, '商品總數': n_zs}) result4_dzspb1['參與打折商品比例'] = result4_dzspb1['打折商品數'] / result4_dzspb1['商品總數'] result4_dzspb1.dropna(inplace = True) result4_sum = result2_data.copy() result4_data = pd.merge(pd.DataFrame(result4_zkld), result4_dzspb1, left_index = True, right_index = True, how = 'inner') result4_data = pd.merge(result4_data,result4_sum,left_index = True, right_index = True, how = 'inner') ''' (2)bokeh作圖 ''' from bokeh.models.annotations import Span # 導入Span模塊 from bokeh.models.annotations import Label # 導入Label模塊 from bokeh.models.annotations import BoxAnnotation # 導入BoxAnnotation模塊 bokeh_data = result4_data[['zkl','sum','參與打折商品比例']] bokeh_data.columns = ['zkl','amount','pre'] bokeh_data['size'] = bokeh_data['amount'] * 0.03 source = ColumnDataSource(bokeh_data) # 創建ColumnDataSource數據 x_mean = bokeh_data['pre'].mean() y_mean = bokeh_data['zkl'].mean() hover = HoverTool(tooltips=[("品牌", "@index"), ("折扣率", "@zkl"), ("商品總數", "@amount"), ("參與打折商品比例", "@pre"), ]) # 設置標簽顯示內容 output_file('project8_pic3.html') p = figure(plot_width=600, plot_height=600, title="各個品牌打折套路解析" , tools=[hover,'box_select,reset,wheel_zoom,pan,crosshair']) # 構建繪圖空間 p.circle_x(x = 'pre',y = 'zkl',source = source,size = 'size', fill_color = 'red',line_color = 'black',fill_alpha = 0.6,line_dash = [8,3]) p.ygrid.grid_line_dash = [6, 4] p.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]) p.add_layout(x) p.add_layout(y) # 繪制輔助線 bg1 = BoxAnnotation(bottom=y_mean, right=x_mean,fill_alpha=0.1, fill_color='olive') label1 = Label(x=0.1, y=0.55,text="少量大打折",text_font_size="10pt" ) p.add_layout(bg1) p.add_layout(label1) # 繪制第一象限 bg2 = BoxAnnotation(bottom=y_mean, left=x_mean,fill_alpha=0.1, fill_color='firebrick') label2 = Label(x=0.7, y=0.55,text="大量大打折",text_font_size="10pt" ) p.add_layout(bg2) p.add_layout(label2) # 繪制第二象限 bg3 = BoxAnnotation(top=y_mean, right=x_mean,fill_alpha=0.1, fill_color='firebrick') label3 = Label(x=0.1, y=0.80,text="少量少打折",text_font_size="10pt" ) p.add_layout(bg3) p.add_layout(label3) # 繪制第三象限 bg4 = BoxAnnotation(top=y_mean, left=x_mean,fill_alpha=0.1, fill_color='olive') label4 = Label(x=0.7, y=0.80,text="少量大打折",text_font_size="10pt" ) p.add_layout(bg4) p.add_layout(label4) # 繪制第四象限 show(p)
結論:
少量少打折:包括雅詩蘭黛、嬌蘭、蘭蔻、薇姿、玉蘭油等共5個品牌。
少量大打折:包括悅詩風吟、蘭芝、歐珀萊等3個品牌。該類品牌的打折商品較少,但折扣力度較大。
大量小打折:包括妮維雅、美寶蓮、蜜絲佛陀等3個品牌。該類型有半數以上的商品都參與了打折活動,但折扣力度並不大。
大量大打折:包括相宜本草、佰草集、自然堂等三大國產品牌。這些品牌不僅有90%以上的商品參與了折扣活動,而且折扣力度很大。