1. 程式人生 > 其它 >9-電商專案實戰

9-電商專案實戰

導包及基礎設定

import re
import os
import glob
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from pandas import Series, DataFrame
import seaborn as sns
from sklearn.linear_model import LinearRegression

sns.set(font_scale=1.2)
plt.rcParams['font.sans-serif'] = 'simhei'
plt.rcParams['axes.unicode_minus'] =False

驅蟲市場潛力分析

# 切換目錄
os.chdir(r'C:\Users\86188\Desktop\Data_Analysis\電商文字挖掘\data\驅蟲劑市場')
filenames1 = glob.glob('*市場近三年交易額.xlsx')
filenames1
'''
['滅鼠殺蟲劑市場近三年交易額.xlsx',
 '電蚊香套裝市場近三年交易額.xlsx',
 '盤香滅蟑香蚊香盤市場近三年交易額.xlsx',
 '蚊香加熱器市場近三年交易額.xlsx',
 '蚊香液市場近三年交易額.xlsx',
 '蚊香片市場近三年交易額.xlsx',
 '防黴防蛀片市場近三年交易額.xlsx']
'''
# 回顧一下re.search包
re.search(r'.*(?=市場)', '滅鼠殺蟲劑市場近三年交易額.xlsx').group()
'''
'滅鼠殺蟲劑'
'''
  • 定義函式,讀取單個excel檔案,轉換成DataFrame,改變列名, 時間列變為datetime型別,並將時間列變為index
def read_3years(filename):
    colname = re.search(r'.*(?=市場)', filename).group()  # 提起檔名中市場前面的文字
    df = pd.read_excel(filename)
    if df['時間'].dtypes == 'int64':
        # 講“時間”列的資料型別轉變為datetime型別
        df['時間'] = pd.to_datetime(df['時間'], unit='D', origin=pd.Timestamp('1899-12-30'))
    df.rename(columns={df.columns[1]:colname}, inplace=True)  # 修改第二列的列名
    df.set_index('時間', inplace=True)
    return df
# 分別讀取七個檔案,並轉換成DataFrame,存入列表中
dfs = [read_3years(filename) for filename in filenames1]
# 將7個DataFrame在axis=1的方向拼接
df = pd.concat(dfs, axis=1).reset_index()
df.head()
  • 檢視各列的資料缺失情況
df.isna().any()
'''
時間          False
滅鼠殺蟲劑       False
電蚊香套裝       False
盤香滅蟑香蚊香盤    False
蚊香加熱器       False
蚊香液         False
蚊香片         False
防黴防蛀片       False
dtype: bool
'''
  • pandas 資料透視表
pandas.pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='All', observed=False)
'''
data:dataframe格式資料
values:需要彙總計算的列,可多選
index:行分組鍵,一般是用於分組的列名或其他分組鍵,作為結果DataFrame的行索引
columns:列分組鍵,一般是用於分組的列名或其他分組鍵,作為結果DataFrame的列索引
aggfunc:聚合函式或函式列表,預設為平均值
fill_value:設定缺失替換值
margins:是否新增行列的總計
dropna:預設為True,如果列的所有值都是NaN,將不作為計算列,False時,被保留
margins_name:彙總行列的名稱,預設為All
observed:是否顯示觀測值
'''
  • 抽取df的所有月份,以供後面使用
month = df['時間'].dt.month
month
'''
0     10
1      9
2      8
3      7
4      6
5      5
6      4
7      3
8      2
9      1
10    12
11    11
12    10
13     9
14     8
15     7
16     6
17     5
18     4
19     3
20     2
21     1
22    12
23    11
24    10
25     9
26     8
27     7
28     6
29     5
30     4
31     3
32     2
33     1
34    12
35    11
Name: 時間, dtype: int64
'''
  • 迴圈預測2018年11月、12月的各子類目的銷售額
for i in [11, 12]:
    dm = df[month==i]  # 從df中抽取對應月份的記錄
    X_train = np.array(dm['時間'].dt.year).reshape(-1, 1)
    y_hat = [pd.datetime(2018, i, 1)]
    for j in range(1, len(dm.columns)):  # 遍歷對應月份的每個種類
        y_train = np.array(dm.iloc[:, j])  # 獲取對應種類的交易金額,作為訓練樣本集的標籤
        linear = LinearRegression()
        linear.fit(X_train, y_train)
        y_predict = linear.predict(np.array([2018]).reshape(-1, 1))
        y_hat.append(y_predict)
    newrow = DataFrame(dict(zip(df.columns, y_hat)))
    df = newrow.append(df)  # 將預測的結果加到df中
df.reset_index(inplace=True)
df.head()
df.drop(columns=['index'], inplace=True)
df.head()
  • 刪除2015年的記錄
df = df[df['時間'].dt.year != 2015]
df.tail()
  • 新增新列,用來儲存每年的交易金額總和
df['colsum'] = df.sum(axis=1)
df.head()
  • 插入一個年份列‘year’
df.insert(1, 'year', df['時間'].dt.year)
df.head()
  • 根據年份分組並對每一組求和,重置索引
byyear = df.groupby('year').sum().reset_index()
byyear.head()

按照年份檢視驅蟲市場總體變化趨勢

sns.relplot('year', 'colsum', data=byyear, kind='line', marker='o', height=4, palette='Set2')
plt.title('近三年驅蟲市場趨勢')
plt.xticks(byyear.year, rotation=45)  # x軸刻度設定,刻度旋轉
plt.xlabel('年份')
plt.ylabel('總交易額')
plt.show()
  • 可以看出:近三年呈增長趨勢,整個市場傾向於成長期和成熟期

檢視各類目市場三年內銷售額總和的變化趨勢

plt.figure(figsize=(10, 6))
# 沒有說明X軸與Y軸的資料,則原資料的索引值作為X軸的資料,每一列的值作為Y軸資料
# dashes設為False,因為預設只能顯示6種種類,設定dashes為False後,不區分線型
sns.lineplot(data=byyear.set_index('year').iloc[:, :-1], marker='^', dashes=False)

for x,y in zip(byyear['year'], byyear['滅鼠殺蟲劑']):
    plt.text(x, y+0.4e8, '%.3e'%y, ha='center', va='bottom')  # 在圖中(x,y)位置加入文字
plt.title('近三年各類目市場銷量趨勢分析')
plt.xlabel('年份')
plt.ylabel('總交易額')
plt.xticks(byyear.year, rotation=45)
plt.legend(prop={'size':10})
plt.show()
  • 直觀的看,滅鼠殺蟲劑和蚊香液都有較大的機會
import statsmodels.api as sm
model = sm.OLS(np.array(dm.iloc[:,1]), np.array([2015,2016,2017]))
results = model.fit()
results.summary()
'''
OLS Regression Results
Dep. Variable:	y	R-squared (uncentered):	0.955
Model:	OLS	Adj. R-squared (uncentered):	0.932
Method:	Least Squares	F-statistic:	42.20
Date:	Thu, 29 Oct 2020	Prob (F-statistic):	0.0229
Time:	08:56:08	Log-Likelihood:	-51.741
No. Observations:	3	AIC:	105.5
Df Residuals:	2	BIC:	104.6
Df Model:	1		
Covariance Type:	nonrobust		
coef	std err	t	P>|t|	[0.025	0.975]
x1	1.705e+04	2624.373	6.496	0.023	5756.519	2.83e+04
Omnibus:	nan	Durbin-Watson:	1.021
Prob(Omnibus):	nan	Jarque-Bera (JB):	0.305
Skew:	-0.216	Prob(JB):	0.859
Kurtosis:	1.500	Cond. No.	1.00

'''

檢視各類目市場三年銷售額綜合的佔比

byyear
# 每個種類在當年的銷售額佔比
byyear_per = byyear.iloc[:,1:-1].div(byyear.colsum, axis=0)
byyear_per
byyear_per.index = byyear.year  # 將byyear_per的索引值設定為byyear的year列對應的值
byyear_per
  • 直接使用byyear_per這個DataFrame畫圖
byyear_per.plot(kind='bar', stacked=True, figsize=(10, 8), colormap='tab10')
plt.legend(loc=(1,0), prop={'size':10})
plt.title('近三年各類目市場銷量佔比', fontdict=dict(fontsize=30))
plt.xlabel('year', fontdict=dict(fontsize=20))
plt.ylabel('總交易額佔比', fontdict=dict(fontsize=20))
plt.xticks(rotation=45)
plt.tick_params(labelsize=18)
# 對於條形圖,X軸位置從0開始
for x,y in zip(range(len(byyear_per)), byyear_per['滅鼠殺蟲劑']):
    plt.text(x, y/2, str(round(y*100,2))+'%', ha='center', va='bottom', size=20)
for m,n in zip(range(len(byyear_per)), byyear_per['蚊香液']):
    plt.text(m, 0.8, str(round(n*100,2))+'%', ha='center', va='bottom', size=20)
plt.show()
# 分別計算各產品在16-17,17-18年間的增長率
byyear_growth = (byyear.iloc[:,1:-1].diff().iloc[1:,:] / byyear.iloc[:,1:-1].shift()).dropna().reset_index(drop=True)
byyear_growth.index = ['16-17', '17-18']
byyear_growth
plt.figure(figsize=(10, 8))
sns.lineplot(data=byyear_growth, dashes=False)  # 不區分線型
plt.title('近三年各類目市場年增幅')
plt.xlabel('年份')
plt.ylabel('總交易額年增幅')
plt.show()
  • 可見除了滅鼠殺蟲劑和蚊香液增幅比較穩定,其它都有下降甚至變負

計算驅蟲市場HHI

df_top100 = pd.read_excel('./top100品牌資料.xlsx')
df_top100.head()
  • 新增“交易指數佔比”列(因為交易指數反應銷售額),代表市場佔有率
df_top100['交易指數佔比'] = df_top100['交易指數'] / df_top100['交易指數'].sum()
df_top100.head()
df_top100.plot(x='品牌', y='交易指數佔比', kind='bar', figsize=(20,6))
plt.tick_params(labelsize=10)
plt.show()
HHI = sum(df_top100['交易指數佔比']**2)
print('HHI是:', str(round(HHI*100, 2))+'%')
print('等效公司數:', round(1/HHI,2))
'''
HHI是: 1.35%
等效公司數: 73.82
'''

滅鼠殺蟲劑市場機會點

產品類別

os.chdir(r'../滅鼠殺蟲劑細分市場/')  # 切換目錄
filenames2 = glob.glob('*.xlsx')
filenames2
'''
['殺蟲.xlsx', '滅鼠.xlsx', '蝨子.xlsx', '蟎.xlsx', '蟑螂.xlsx']
'''
dfs2 = [pd.read_excel(filename) for filename in filenames2]
df2 = pd.concat(dfs2, sort=False)  # sort=False關閉警告,合併列表中的5個DataFrame
df2.isna().sum()
類別         0
時間         0
頁碼         0
排名         0
連結         0
        ... 
寶貝成份    6556
規格:     6556
樟腦      6556
包裝      6556
產品名     6556
Length: 229, dtype: int64
col_index = df2.isna().mean() > 0.98  # 檢視每一列的缺失值是否超過98%
df21 = df2.loc[:,~col_index]  # 刪除缺失值佔比超過98%的特徵
ser = Series([4,5,3,3,7,8,8,9])
ser.unique()
'''
array([4, 5, 3, 7, 8, 9], dtype=int64)
'''
ser.nunique()
'''
6
'''
col_index2 = np.array([df21[colname].nunique()==1 for colname in df21.columns])
df22 = df21.loc[:,~col_index2]  # 刪除特徵值完全一致的特徵
len(df22.columns)
'''
37
'''
col_index3 = df22.columns.get_loc('藥品登記號')  # 獲取“藥品登記號”列的索引位置
df23 = df22.iloc[:,:col_index3]
len(df23.columns)
'''
24
'''
useless = ['時間','連結','主圖連結','主圖視訊連結','頁碼','排名','寶貝標題','運費','下架時間','旺旺']
df24 = df23.drop(columns=useless)
len(df24.columns)
'''
14
'''
df24.dtypes
'''
類別         object
寶貝ID        int64
銷量(人數)      int64
售價        float64
預估銷售額     float64
評價人數      float64
收藏人數        int64
地域         object
店鋪型別       object
品牌         object
型號         object
淨含量        object
適用物件       object
物理形態       object
dtype: object
'''
df25 = df24.astype({'寶貝ID':'object'})
df25.reset_index(drop=True, inplace=True)
df25.dtypes
'''
類別         object
寶貝ID       object
銷量(人數)      int64
售價        float64
預估銷售額     float64
評價人數      float64
收藏人數        int64
地域         object
店鋪型別       object
品牌         object
型號         object
淨含量        object
適用物件       object
物理形態       object
dtype: object
'''
df25.describe()
df25.head()
byclass = df25['預估銷售額'].groupby(df25['類別']).sum()
byclass.plot.barh(color=['green', 'red', 'yellow', 'blue', 'grey'])
plt.show()
byclass.plot.pie(autopct='%.2f%%')  # 使用Series物件繪製餅圖
plt.show()
  • 可以看出重點需要研究的市場是滅鼠和蟑螂,這裡我們選擇滅鼠

滅鼠類別分析

# 選擇滅鼠資料
df26 = df25[df25['類別']=='滅鼠']
df26.head()
bins = [0,50,100,150,200,250,300,500]  # 售價劃分刻度
lables = ['0_50','50_100','100_150','150_200','200_250','250_300','300以上']
# 劃分價格區間並將其作為一列新增到原始的DATa Frame中
df26['價格區間'] = pd.cut(df26['售價'],bins=bins,labels=lables,include_lowest=True)
df26.head()
  • 編寫函式,根據指定欄位分組,組裝新的DataFrame
def by_function(df,by,sort='單寶貝平均銷售額'):
    bytype = df.groupby(by).sum().loc[:,['預估銷售額']]  # 特別注意,抽取的列名加中括號保證是DataFrame
    bytype['銷售額佔比'] = bytype['預估銷售額'] / bytype['預估銷售額'].sum()
    bytype['寶貝數'] = df.groupby(by).nunique()['寶貝ID']
    bytype['寶貝數佔比'] = bytype['寶貝數'] / bytype['寶貝數'].sum()
    bytype['單寶貝平均銷售額'] = bytype['預估銷售額'] / bytype['寶貝數']
    bytype['相對競爭度'] = 1 - (bytype['單寶貝平均銷售額']-bytype['單寶貝平均銷售額'].min())/(bytype['單寶貝平均銷售額'].max()-bytype['單寶貝平均銷售額'].min())
    if sort:
        bytype.sort_values(sort, ascending=False, inplace=True)
    return bytype
by_price = by_function(df26,'價格區間')
by_price
  • 編寫繪圖函式繪製“相對競爭度”和“銷售額佔比”
def draw_plot(df,figsize=(10,6),rotation=30):
    ax = df.plot(y='相對競爭度', marker='o',figsize=figsize, c='b',lw=2)
    df.plot(y='銷售額佔比',kind='bar',color='wheat',alpha=0.8,ax=ax)
    plt.legend(loc=2)
    plt.xticks(rotation=rotation)
    plt.show()
draw_plot(by_price)
  • 結果依單寶貝銷售額降序,即依競爭度升序,這裡銷售額佔比可以理解為市場份額

  • 可見0-50容量大,競爭大,大容量市場(對比的是50-100,容量小,競爭稍小)

  • 200-250,競爭小,做高價市場的優先選擇,屬於機會點

  • 可見我們喜歡的類目是:市場份額高(表示更適合大眾),相對競爭度低(沒人搶).也就是找到悶聲發大財的那些個分類去分蛋糕

滅鼠類別0_50細分價格市場

df26.head()
# 選擇滅鼠種類,價格區間在“0-50”的資料作為DataFrame
df50 = df26[df26['價格區間']=='0_50']
df50.head()
bins2 = [0,10,20,30,40,50]  # 售價劃分刻度
lables2 = ['0_10','10_20','20_30','30_40','40_50']
# 劃分價格區間並將其作為一列新增到原始的DataFrame中
df50['價格子區間'] = pd.cut(df50['售價'],bins=bins2,labels=lables2,include_lowest=True)
df50.head()
byprice_sub = by_function(df50,'價格子區間')
draw_plot(byprice_sub)
  • 可見10-20競爭度低,容量大,優選,20-30也不錯
  • 200-250細分市場也是同樣的分析思路
# 選擇滅鼠種類,價格區間在“0-50”的資料作為DataFrame
df200_250 = df26[df26['價格區間']=='200_250']
df200_250.head()
bins3 = [200,210,220,230,240,250]  # 售價劃分刻度
lables3 = ['200_210','210_220','220_230','230_240','240_250']
# 劃分價格區間並將其作為一列新增到原始的DataFrame中
df200_250['價格子區間'] = pd.cut(df200_250['售價'],bins=bins3,labels=lables3,include_lowest=True)
df200_250.head()
byprice_sub2 = by_function(df200_250,'價格子區間')
figsize=(10,6)
ax = byprice_sub2.plot(y='相對競爭度', marker='o',figsize=figsize, c='b',lw=2)
byprice_sub2.plot(y='銷售額佔比',kind='bar',color='wheat',alpha=0.8,ax=ax)
plt.legend(loc=4)
plt.xticks(rotation=45)
plt.show()
  • 可見210-220競爭度低,容量大,優選

  • 根據店鋪型別分組並繪圖

byshop = by_function(df50,'店鋪型別')
draw_plot(byshop)
  • 選取預估銷售額排名前5%的商品,按照型號分組,並按照預估銷售額排序並繪圖
byshape = by_function(df50,'型號', sort='預估銷售額')
df95 = byshape[byshape['預估銷售額']>byshape['預估銷售額'].quantile(0.95)]  # 分位數
draw_plot(df95,rotation=90)
  • 可見雖然粘鼠板市場份額普遍較高,但是0005,MT007在競爭度上有明顯的優勢
by_wuli = by_function(df50, '物理形態')
draw_plot(by_wuli)
  • 通過['物理形態','淨含量']分組,通過['物理形態','預估銷售額']排序;並製圖
by_common = by_function(df50,['物理形態','淨含量'],sort=['物理形態','預估銷售額'])
draw_plot(by_common,figsize=(30,8),rotation=90)

競爭分析——產品類目,適用物件

os.chdir(r'../競爭資料/商品銷售資料/')  # 切換目錄
filenames3 = glob.glob('*.xlsx')
filenames3
'''
['安速家居近30天銷售資料.xlsx', '拜耳近30天銷售資料.xlsx', '科凌蟲控旗艦店近30天銷售資料.xlsx']
'''
def read_sales(filename):
    df = pd.read_excel(filename)
    useless = ['序號','店鋪名稱','商品名稱','主圖連結','商品連結']
    df.drop(columns=useless, inplace=True)
    return df
dfs3 = [read_sales(filename) for filename in filenames3]
df_bai = dfs3[1]  # 拜耳的DataFrame
df_an = dfs3[0]
df_ke = dfs3[2]
  • 通過類目分組,對各個公司30天銷售記錄分組,並畫餅圖
df_bai_category = df_bai.groupby('類目').sum()  # 通過類目分組並求和
df_an_category = df_an.groupby('類目').sum()
df_ke_category = df_ke.groupby('類目').sum()
df_bai_category
current_palette = sns.color_palette('bright')
sns.set_palette(current_palette)
fig, axes = plt.subplots(1,3,figsize=(16, 5))  # 規劃繪圖區域,返回影象和繪圖區域陣列
ax = axes[0]  # 選擇第一個繪圖區域
df_bai_category['銷售額'].plot.pie(autopct='%.2f%%', ax=ax, startangle=30, title='拜爾')
ax.set_ylabel('')
ax = axes[1]
df_an_category['30天銷售額'].plot.pie(autopct='%.2f%%', ax=ax, startangle=60, title='安速')
ax.set_ylabel('')
ax = axes[2]
df_ke_category['30天銷售額'].plot.pie(autopct='%.2f%%', ax=ax, startangle=90, title='科凌')
ax.set_ylabel('')
plt.show()
  • 可見拜耳只有一個市場,其他的有不同市場,但主要市場都是滅鼠殺蟲劑
# 看不清可以畫複合餅圖
current_palette = sns.color_palette('bright')
sns.set_palette(current_palette)
plt.figure(figsize=(16,5))
axes1 = plt.subplot(1,3,1)
axes1.pie(df_bai_category['銷售額'],labels=df_bai_category.index, autopct='%.2f%%',startangle=30,shadow=True)
axes1.set_title('拜耳')

axes2 = plt.subplot(1,3,2)
axes2.pie(df_an_category['30天銷售額'],labels=df_an_category.index, autopct='%.2f%%',startangle=30,shadow=True, explode=[0.4]*6)
axes2.set_title('安速')
  • 通過適用物件分組,對各個公司30天銷售記錄分組,並畫餅圖
df_bai_use = df_bai.groupby('使用物件').sum()  # 通過類目分組並求和
df_an_use = df_an.groupby('適用物件').sum()
df_ke_use = df_ke.groupby('適用物件').sum()
current_palette = sns.color_palette('bright')
sns.set_palette(current_palette)
fig, axes = plt.subplots(1,3,figsize=(16, 5))  # 規劃繪圖區域,返回影象和繪圖區域陣列
ax = axes[0]  # 選擇第一個繪圖區域
df_bai_use['銷售額'].plot.pie(autopct='%.2f%%', ax=ax, startangle=30, title='拜爾')
ax.set_ylabel('')
ax = axes[1]
df_an_use['30天銷售額'].plot.pie(autopct='%.2f%%', ax=ax, startangle=60, title='安速')
ax.set_ylabel('')
ax = axes[2]
df_ke_use['30天銷售額'].plot.pie(autopct='%.2f%%', ax=ax, startangle=90, title='科凌')
ax.set_ylabel('')
plt.show()
  • 拜耳的主要物件是蟑螂,而另外兩家除此之外還有蟎,鼠
  • 而從之前的分析看滅鼠和蟑螂的整體市場份額都大
  • 應該開拓新市場,尤其是滅鼠,也考察其他兩家都開拓的蟎市場

競爭分析-產品結構

拜耳公司產品結構分析

os.chdir(r'../商品交易資料/')
filenames4 = glob.glob('*.xlsx')
filenames4
'''
['安速全店商品交易資料.xlsx', '拜耳全店商品交易資料.xlsx', '科凌蟲控全店商品交易資料.xlsx']
'''
df_bai_trade = pd.read_excel(filenames4[1])
df_bai_trade.head()
# 根據“商品”進行分組,組裝成一個新的DataFrame並返回
def product_func(df):
    df_pro = df.groupby('商品').mean().loc[:,['交易增長幅度']]  # 商品分組求均值,獲取交易增長幅度列
    df_pro['交易金額'] = df.groupby('商品').sum().loc[:,'交易金額']
    df_pro['交易金額佔比'] = df_pro['交易金額'] / df_pro['交易金額'].sum()
    df_pro['商品個數'] = df.groupby('商品').count()['交易金額']
    df_pro.reset_index(inplace=True)
    return df_pro
# 根據商品分類對拜耳的DataFrame重組
df_bai_product = product_func(df_bai_trade)
df_bai_product.head()
df_bai_product.describe()
  • 編寫蓋帽函式,將0.9分位數以上的資料,都替換為0.9分位數
# 蓋帽法
def block(ser):
    qu = ser.quantile(0.9)  # 獲取0.9分位數
    result = ser.mask(ser>qu, qu)  # 將大於0.9分位數的資料,替換成0.9分位數
    return result
def block_product(df):
    df_copy = df.copy()
    df_copy['交易增長幅度'] = block(df_copy['交易增長幅度'])
    df_copy['交易金額佔比'] = block(df_copy['交易金額佔比'])
    return df_copy
  • 呼叫編寫的蓋帽函式,將兩列“冒尖”的資料進行蓋帽
df_bai_block = block_product(df_bai_product)
df_bai_block.describe()
  • 繪製波士頓矩陣
def plotBCG(df,mean=False,q1=0.5,q2=0.5):
    plt.subplots(figsize=(10,8))
    ax = sns.scatterplot('交易金額佔比','交易增長幅度',data=df,
                        hue='商品個數',size='商品個數',sizes=(20,200),
                        palette='cool')  # 繪製散點圖
    # for i in range(len(df)):
    #     ax.text(df['交易金額佔比'][i],df['交易增長幅度'][i],i)
    if mean:
        plt.axvline(df['交易金額佔比'].mean())
        plt.axhline(df['交易增長幅度'].mean())
    else:
        plt.axvline(df['交易金額佔比'].quantile(q1))
        plt.axhline(df['交易增長幅度'].quantile(q2))
    plt.show()
plotBCG(df_bai_block)
  • 自定義區分產品結構的函式
def extractBCG(df,q1=0.5,q2=0.5,sort='交易金額佔比'):
    star = df.loc[(df['交易金額佔比']>=df['交易金額佔比'].quantile(q1))&
                  (df['交易增長幅度']>=df['交易增長幅度'].quantile(q2)),:]
    star = star.sort_values(sort, ascending=False)
    cow = df.loc[(df['交易金額佔比']>=df['交易金額佔比'].quantile(q1))&
                  (df['交易增長幅度']<df['交易增長幅度'].quantile(q2)),:]
    cow = cow.sort_values(sort, ascending=False)
    question = df.loc[(df['交易金額佔比']<df['交易金額佔比'].quantile(q1))&
                  (df['交易增長幅度']>=df['交易增長幅度'].quantile(q2)),:]
    qusetion = question.sort_values(sort, ascending=False)
    return star, cow, question
star,cow,question = extractBCG(df_bai_product)
star1,cow1,question1 = extractBCG(df_bai_product, sort='交易增長幅度')
star
star1
cow
question

安速產品結構分析

df_an_trade = pd.read_excel(filenames4[0])
df_an_product = product_func(df_an_trade)
df_an_block = block_product(df_an_product)  # 蓋帽
plotBCG(df_an_block)
star_an,cow_an,question_an = extractBCG(df_an_product)
star_an1,cow_an1,question_an1 = extractBCG(df_an_product, sort='交易增長幅度')
star_an
cow_an
question_an

科凌產品結構分析

df_ke_trade = pd.read_excel(filenames4[2])
df_ke_product = product_func(df_ke_trade)
df_ke_block = block_product(df_ke_product)  # 蓋帽
plotBCG(df_ke_block)
star_ke,cow_ke,question_ke = extractBCG(df_ke_product)
star_ke1,cow_ke1,question_ke1 = extractBCG(df_ke_product, sort='交易增長幅度')
star_ke

競爭分析—流量渠道

os.chdir('../流量渠道資料/')  # 切換目錄
filenames5 = glob.glob('*.xlsx')
filenames5
'''
['安速家居旗艦店流量渠道.xlsx', '拜耳官方旗艦店流量渠道.xlsx', '科凌蟲控旗艦店流量渠道.xlsx']
'''

拜耳流量分析

df_bai_flow = pd.read_excel(filenames5[1])
df_bai_flow.head()
  • 編寫交易指數排名前10的記錄的函式
def flow_top10(df):
    df_copy = df.copy()
    df_top10 = df_copy.sort_values('交易指數', ascending=False).reset_index(drop=True).iloc[:10,:]
    df_top10.set_index('流量來源', inplace=True)
    return df_top10
df_bai_top10 = flow_top10(df_bai_flow)  # 呼叫函式,返回交易指數排名前10的記錄
df_bai_top10
  • 編寫繪製交易指數佔比的餅圖,注意某些流量來源要離圓心一些距離
def draw_flow(df):
    paid = ['付費流量', '直通車', '淘寶客', '淘寶聯盟']  # 需要付費的流量來源
    flow_index = np.array([True if name in paid else False for name in df.index])
    explode_value = flow_index * 0.1
    ax = df['交易指數'].plot.pie(autopct='%.2f%%', explode=explode_value, figsize=(8,8),colormap='cool')
    ax.set_ylabel("")
    trade_index_sum = df['交易指數'].sum()
    trade_paid_index = df['交易指數'][flow_index].sum()
    trade_paid_percent = trade_paid_index / trade_index_sum
    plt.xlabel(f'前10流量中:總交易指數:{trade_index_sum};付費流量佔比{trade_paid_percent};付費流量帶來交易指數:{trade_paid_index}')
draw_flow(df_bai_top10)

安速流量分析

df_an_flow = pd.read_excel(filenames5[0])
df_an_flow.head()
df_an_top10 = flow_top10(df_an_flow)  # 呼叫函式,返回交易指數排名前10的記錄
df_an_top10
draw_flow(df_an_top10)
  • 可見拜耳和安速的流量配比是差不多的,安速的整體流量小很多,即流量效果拜耳明顯 優於安速

科凌流量分析

df_ke_flow = pd.read_excel(filenames5[2])
df_ke_flow.head()
df_ke_top10 = flow_top10(df_ke_flow)  # 呼叫函式,返回交易指數排名前10的記錄
draw_flow(df_ke_top10)
  • 和拜耳在流量上差不多,科凌蟲控付費佔比較高
  • 可見拜耳在流量結構上是有優勢的,要保持這個優勢

輿情分析-文字挖掘

os.chdir('../評論輿情資料/')
filenames6 = glob.glob('*.xlsx')
filenames6
'''
['安速.xlsx', '德國拜耳.xlsx', '科林蟲控.xlsx']
'''
df_bai_comment = pd.read_excel(filenames6[1])
df_bai_comment
comment_list = list(df_bai_comment['評論'])  # 抽出評論列,並轉換為list
# 替換非中英文字元為空格
comment_list_2 = [re.sub(r'[^a-zA-Z\u4E00-\u9FA5]+',' ',comment) for comment in comment_list]
# 讀取停用詞,轉換成停用詞列表
stopwords = list(pd.read_csv('../../百度停用詞表.txt',names=['stopwords'],engine='python')['stopwords'])
import jieba
# jieba.lcut('中華人民共和國萬歲')  # 精確模式
jieba.lcut('中華人民共和國萬歲',cut_all=True)  # 全模式
'''
['中華', '中華人民', '中華人民共和國', '華人', '人民', '人民共和國', '共和', '共和國', '萬歲']
'''
comment_list3 = []
for comment in comment_list_2:  # 遍歷每一條評論
    words = jieba.lcut(comment)  # 精確模式,沒有冗餘,對每一條評論進行結巴分詞
    index = np.array([len(word)>1 for word in words])  # 判斷每個分詞的長度是否大於1
    ser1 = Series(words)
    ser2 = ser1[index]  # 篩選分詞長度大於1的分詞
    ser3 = ser2[~ser2.isin(stopwords)].unique()  # 篩選出不在停用詞表的分詞,並去重
    if len(ser3) > 0:
        comment_list3.append(list(ser3))
# 將所有分詞儲存到一個列表中
word_list = [word for comlist in comment_list3 for word in comlist]
comment_str = ' '.join(word_list)  # 將列表中所有的分詞拼接成一個字串
  • 繪製詞雲圖
from wordcloud import WordCloud
import imageio
leaf = imageio.imread('../../leaf.jpg')
wc = WordCloud(background_color='wheat',font_path='../../SimHei.ttf', mask=leaf)  # 建立WordCloud物件
wc.generate(comment_str)  # 傳入拼接好的評論字串,生成詞雲
plt.figure(figsize=(6,8))
plt.imshow(wc)  # 繪製詞雲圖
plt.axis('off')
plt.show()
wc.to_file('../../拜耳輿情詞雲.jpg')  # 儲存詞雲圖到指定位置
  • 計算TF-IDF值,提取關鍵詞
import jieba.analyse
jieba.analyse.extract_tags(comment_str,topK=20,withWeight=True)