天天看點

某寶爬取商品的資料分析成圖總結1.資料清洗2.标題關鍵字與價格分析3.銷量與價格、地區的關系3. 函數分布

文章目錄

  • 1.資料清洗
  • 2.标題關鍵字與價格分析
    • 2.1 商品标題詞雲圖
    • 2.2 關鍵詞柱狀圖
    • 2.3 标題高頻關鍵字與平均銷量關系
    • 2.4 标題高頻關鍵字與平均售價關系
  • 3.銷量與價格、地區的關系
    • 3.1 商品價格、銷量區間分布
    • 3.2 商品價格與平均銷量關系分析
    • 3.3 全國商家數量分布
    • 3.4 省份與總銷量的分布
    • 3.5 全國商家省份平均銷量分布
  • 3. 函數分布
    • 3.1 分析标題關鍵字與其他屬性的關系analysis_title_keywords()
    • 3.2 分析商品某數值區間分布柱狀體 cut_and_sort_data()

原文

本文主要為為pyecharts制圖技術總結

1.資料清洗

資料清洗主要是将資料價格變換與資料銷量規約

import numpy as np
import pandas as pd
import jieba.analyse
from pyecharts import options as opts
from pyecharts.globals import SymbolType
from pyecharts.charts import Pie, Bar, Map, WordCloud


# 淘寶商品原生excel檔案儲存路徑
GOODS_EXCEL_PATH = 'taobao_goods.xlsx'
# 淘寶商品标準excel檔案儲存路徑
GOODS_STANDARD_EXCEL_PATH = 'taobao_goods_standard1.xlsx'
# 清洗詞
STOP_WORDS_FILE_PATH = 'stop_words.txt'
# 讀取标準資料
DF_STANDARD = pd.read_excel(GOODS_STANDARD_EXCEL_PATH)
print(DF_STANDARD.head())
           
某寶爬取商品的資料分析成圖總結1.資料清洗2.标題關鍵字與價格分析3.銷量與價格、地區的關系3. 函數分布

代碼如下:

def standard_data():
    """
    處理淘寶爬取下來的原生資料
    例:
        1.5萬人付款 -> 15000
        廣州 廣州 -> 廣州
    :return:
    """
    df = pd.read_excel(GOODS_EXCEL_PATH)
    # 1、将價格轉化為整數型
    raw_sales = df['sales'].values
    new_sales = []
    for sales in raw_sales:
        sales = sales[:-3]
        sales = sales.replace('+', '')
        if '萬' in sales:
            sales = sales[:-1]
            if '.' in sales:
                sales = sales.replace('.', '') + '000'
            else:
                sales = sales + '0000'
        sales = int(sales)
        new_sales.append(sales)
    df['sales'] = new_sales
    print(df['sales'].values)

    # 2、将地區轉化為隻包含省
    raw_location = df['location'].values
    new_location = []
    for location in raw_location:
        if ' ' in location:
            location = location[:location.find(' ')]
        new_location.append(location)
    # df.location與df[location]效果類似
    df.location = new_location
    print(df['location'].values)

    # 3、生成新的excel
    writer = pd.ExcelWriter(GOODS_STANDARD_EXCEL_PATH)
    # columns參數用于指定生成的excel中列的順序
    df.to_excel(excel_writer=writer, columns=['title', 'price', 'location', 'sales', 'comment_url'], index=False,
                encoding='utf-8', sheet_name='Sheet')
    writer.save()
    writer.close()
           

2.标題關鍵字與價格分析

2.1 商品标題詞雲圖

商品标題詞數統計 (‘情趣’, 1.0), (‘尿酸’, 0.44688260908416977)’,…)

2.2 關鍵詞柱狀圖

商品标題詞頻 {‘女性’: 156, ‘夜場’: 150, ‘光面’: 163, ‘男女’: 174…)

某寶爬取商品的資料分析成圖總結1.資料清洗2.标題關鍵字與價格分析3.銷量與價格、地區的關系3. 函數分布

2.3 标題高頻關鍵字與平均銷量關系

某寶爬取商品的資料分析成圖總結1.資料清洗2.标題關鍵字與價格分析3.銷量與價格、地區的關系3. 函數分布

2.4 标題高頻關鍵字與平均售價關系

某寶爬取商品的資料分析成圖總結1.資料清洗2.标題關鍵字與價格分析3.銷量與價格、地區的關系3. 函數分布
def analysis_title():
    """
    詞雲分析商品标題
    :return:
    """
    # 引入全局資料
    global DF_STANDARD
    # 資料清洗,去掉無效詞
    jieba.analyse.set_stop_words(STOP_WORDS_FILE_PATH)
    # 1、詞數統計
    keywords_count_list = jieba.analyse.textrank(' '.join(DF_STANDARD.title), topK=50, withWeight=True)
    print('詞數統計',keywords_count_list)
    #[('情趣', 1.0), ('尿酸', 0.44688260908416977), ('6753732687),('螺紋', 0.3208201974264058)
    # 生成詞雲
    word_cloud = (
        WordCloud()
            .add("", keywords_count_list, word_size_range=[20, 100], shape=SymbolType.DIAMOND)
            .set_global_opts(title_opts=opts.TitleOpts(title="避孕套功能詞雲TOP50"))
    )
    word_cloud.render('title-word-cloud.html')


    # 2、避孕套商品标題詞頻分析生成柱狀圖
    # 2.1統計詞數
    # 取前20高頻的關鍵詞
    keywords_count_dict = {i[0]: 0 for i in reversed(keywords_count_list[:20])}
                            #{'女性': 0, '夜場': 0,
    print('取前20高頻的關鍵詞',keywords_count_dict)
    #{'女性': 0, '夜場': 0, '光面': 0, '男女': 0, '計生': 0, '水溶性': 0, '震動': 0, '免洗': 0, '狼牙': 0, '油量': 0, '帶刺': 0, '延時': 0, '學生': 0, '潤滑': 0, '螺紋': 0, '男用': 0, '成人': 0, '顆粒': 0, '尿酸': 0, '情趣': 0}
    cut_words = jieba.cut(' '.join(DF_STANDARD.title))
    for word in cut_words:
        for keyword in keywords_count_dict.keys():
            if word == keyword:
                keywords_count_dict[keyword] = keywords_count_dict[keyword] + 1
    print(keywords_count_dict)
    #{'女性': 156, '夜場': 150, '光面': 163, '男女': 174, '計生': 165, '水溶性': 204, '震動': 174, '免洗': 200, '狼牙': 111, '油量': 266, '帶刺': 245, '延時': 273, '學生': 288, '潤滑': 301, '螺紋': 341, '男用': 361, '成人': 328, '顆粒': 441, '尿酸': 776, '情趣': 1150}
    

	# 2.2生成柱狀圖
    keywords_count_bar = (
        Bar()
            .add_xaxis(list(keywords_count_dict.keys()))
            .add_yaxis("", list(keywords_count_dict.values()))
            .reversal_axis()
            .set_series_opts(label_opts=opts.LabelOpts(position="right"))
            .set_global_opts(
            title_opts=opts.TitleOpts(title="商品功能TOP20"),
            yaxis_opts=opts.AxisOpts(name="功能"),
            xaxis_opts=opts.AxisOpts(name="商品數")
        )
    )
    keywords_count_bar.render('title-word-count-bar.html')


    # 3、标題高頻關鍵字與平均銷量關系
    keywords_sales_dict = analysis_title_keywords(keywords_count_list, 'sales', 20)
	#keywords_count_list 詞數統計 [('情趣', 1.0), ('尿酸', 0.44688260908416977), ...]
    # 生成柱狀圖
    keywords_sales_bar = (
        Bar()
            .add_xaxis(list(keywords_sales_dict.keys()))
            .add_yaxis("", list(keywords_sales_dict.values()))
            .reversal_axis()
            .set_series_opts(label_opts=opts.LabelOpts(position="right"))
            .set_global_opts(
            title_opts=opts.TitleOpts(title="商品功能與平均銷量TOP20"),
            yaxis_opts=opts.AxisOpts(name="功能"),
            xaxis_opts=opts.AxisOpts(name="平均銷量")
        )
    )
    keywords_sales_bar.render('title-word-sales-bar.html')



    # 4、标題高頻關鍵字與平均售價關系
    keywords_price_dict = analysis_title_keywords(keywords_count_list, 'price', 20)
    # 生成柱狀圖
    keywords_price_bar = (
        Bar()
            .add_xaxis(list(keywords_price_dict.keys()))
            .add_yaxis("", list(keywords_price_dict.values()))
            .reversal_axis()
            .set_series_opts(label_opts=opts.LabelOpts(position="right"))
            .set_global_opts(
            title_opts=opts.TitleOpts(title="商品功能與平均售價TOP20"),
            yaxis_opts=opts.AxisOpts(name="功能"),
            xaxis_opts=opts.AxisOpts(name="平均售價")
        )
    )
    keywords_price_bar.render('title-word-price-bar.html')
           

3.銷量與價格、地區的關系

3.1 商品價格、銷量區間分布

def analysis_price():
    """
    分析商品價格
    :return:
    """
    # 引入全局資料
    global DF_STANDARD
    # 設定切分區域
    price_list_bins = [0, 20, 40, 60, 80, 100, 120, 150, 200, 1000000]
    # 設定切分後對應标簽
    price_list_labels = ['0-20', '21-40', '41-60', '61-80', '81-100', '101-120', '121-150', '151-200', '200以上']
    # 分區統計
    price_count = cut_and_sort_data(price_list_bins, price_list_labels, DF_STANDARD.price)
    print(price_count)
    #{'0-20': 471, '21-40': 778, '41-60': 480, '61-80': 269, '81-100': 170, '101-120': 64, '121-150': 104, '151-200': 134, '200以上': 38}
    # 生成柱狀圖
    bar = (
        Bar()
            .add_xaxis(list(price_count.keys()))
            .add_yaxis("", list(price_count.values()))
            .set_global_opts(
            title_opts=opts.TitleOpts(title="避孕套商品價格區間分布柱狀體"),
            yaxis_opts=opts.AxisOpts(name="個商品"),
            xaxis_opts=opts.AxisOpts(name="商品售價:元")
        )
    )
    bar.render('price-bar.html')
    # 生成餅圖
    age_count_list = [list(z) for z in zip(price_count.keys(), price_count.values())]
    pie = (
        Pie()
            .add("", age_count_list)
            .set_global_opts(title_opts=opts.TitleOpts(title="避孕套商品價格區間餅圖"))
            .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
    )
    pie.render('price-pie.html')
           
某寶爬取商品的資料分析成圖總結1.資料清洗2.标題關鍵字與價格分析3.銷量與價格、地區的關系3. 函數分布
def analysis_sales():
    """
    銷量情況分布
    :return:
    """
    # 引入全局資料
    global DF_STANDARD
    # 設定切分區域
    listBins = [0, 1000, 5000, 10000, 50000, 100000, 1000000]
    # 設定切分後對應标簽
    listLabels = ['一千以内', '一千到五千', '五千到一萬', '一萬到五萬', '五萬到十萬', '十萬以上']
    # 分區統計
    sales_count = cut_and_sort_data(listBins, listLabels, DF_STANDARD.sales)
    print(sales_count) # {'一千以内': 2273, '一千到五千': 194,...] 
    # 生成柱狀圖
    bar = (
        Bar()
            .add_xaxis(list(sales_count.keys()))
            .add_yaxis("", list(sales_count.values()))
            .set_global_opts(
            title_opts=opts.TitleOpts(title="避孕套商品銷量區間分布柱狀圖"),
            yaxis_opts=opts.AxisOpts(name="個商品"),
            xaxis_opts=opts.AxisOpts(name="銷售件數")
        )
    )
    bar.render('sales-bar.html')
    # 生成餅圖
    age_count_list = [list(z) for z in zip(sales_count.keys(), sales_count.values())]
    pie = (
        Pie()
            .add("", age_count_list)
            .set_global_opts(title_opts=opts.TitleOpts(title="避孕套商品銷量區間餅圖"))
            .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
    )
    pie.render('sales-pie.html')
           
某寶爬取商品的資料分析成圖總結1.資料清洗2.标題關鍵字與價格分析3.銷量與價格、地區的關系3. 函數分布

3.2 商品價格與平均銷量關系分析

def analysis_price_sales():
    """
    商品價格與銷量關系分析
    :return:
    """
    # 引入全局資料
    global DF_STANDARD
    df = DF_STANDARD.copy()
    df['group'] = pd.qcut(df.price, 12)
    df.group.value_counts().reset_index()
    df_group_sales = df[['sales', 'group']].groupby('group').mean().reset_index()
    df_group_str = [str(i) for i in df_group_sales['group']]
    print(df_group_str)
    #['(0.649, 10.092]', '(10.092, 19.9]',]
    # 生成柱狀圖
    bar = (
        Bar()
            .add_xaxis(df_group_str)
            .add_yaxis("", list(df_group_sales['sales']), category_gap="50%")
            .set_global_opts(
            title_opts=opts.TitleOpts(title="避孕套商品價格分區與平均銷量柱狀圖"),
            yaxis_opts=opts.AxisOpts(name="價格區間"),
            xaxis_opts=opts.AxisOpts(name="平均銷量", axislabel_opts={"rotate": 30})
        )
    )
    bar.render('price-sales-bar.html')
           
某寶爬取商品的資料分析成圖總結1.資料清洗2.标題關鍵字與價格分析3.銷量與價格、地區的關系3. 函數分布

3.3 全國商家數量分布

某寶爬取商品的資料分析成圖總結1.資料清洗2.标題關鍵字與價格分析3.銷量與價格、地區的關系3. 函數分布
某寶爬取商品的資料分析成圖總結1.資料清洗2.标題關鍵字與價格分析3.銷量與價格、地區的關系3. 函數分布

3.4 省份與總銷量的分布

3.5 全國商家省份平均銷量分布

某寶爬取商品的資料分析成圖總結1.資料清洗2.标題關鍵字與價格分析3.銷量與價格、地區的關系3. 函數分布
def analysis_province_sales():
    """
    省份與銷量的分布
    :return:
    """
    # 引入全局資料
    global DF_STANDARD

    # 1、全國商家數量分布
    province_sales = DF_STANDARD.location.value_counts()
    province_sales_list = [list(item) for item in province_sales.items()]
    print(province_sales_list)
	#[['廣東', 647], ['上海', 471], ]
	
    # 1.1 生成熱力圖
    province_sales_map = (
        Map()
            .add("前兩千款避孕套商家數量全國分布圖", province_sales_list, "china")
            .set_global_opts(
            visualmap_opts=opts.VisualMapOpts(max_=647),
        )
    )
    province_sales_map.render('province-seller-map.html')
    #print('1.2' ,province_sales.index.tolist())
    #['廣東', '上海', '浙江', '江蘇', '北京', '山東', '福建', '安徽', '湖北', '河南', '四川', '湖南', '山西',
    # '江西', '陝西', '廣西', '天津', '遼甯', '河北', '重慶', '日本', '吉林', '德國', '黑龍江', 
    #'雲南', '海外', '甘肅', '甯夏', '美國']
   
    # 1.2 生成柱狀圖
    province_sales_bar = (
        Bar()
            .add_xaxis(province_sales.index.tolist())
            .add_yaxis("", province_sales.values.tolist(), category_gap="50%")
            .set_global_opts(
            title_opts=opts.TitleOpts(title="前兩千款避孕套商家數量地區柱狀圖"),
            yaxis_opts=opts.AxisOpts(name="商家數量"),
            xaxis_opts=opts.AxisOpts(name="地區", axislabel_opts={"rotate": 90})
        )
    )
    province_sales_bar.render('province-seller-bar.html')

    # 2、全國商家省份銷量總和分布(未成功,原因待查)
    province_sales_sum = DF_STANDARD.pivot_table(index='location', values='sales', aggfunc=np.sum)
    # 根據銷量排序
    province_sales_sum.sort_values('sales', inplace=True, ascending=False)
    province_sales_sum_list = [list(item) for item in
                               zip(province_sales_sum.index, np.ravel(province_sales_sum.values))]
    print(province_sales_sum_list)
	#[['廣東', 520770], ['上海', 336154], ['江蘇', 103786],]

    # 2.1 生成熱力圖
    province_sales_sum_map = (
        Map()
            .add("前兩千款避孕套各省商家銷量總和全國分布圖", province_sales_sum_list, "china")
            .set_global_opts(
            visualmap_opts=opts.VisualMapOpts(max_=5000),
        )
    )
    province_sales_sum_map.render('province-sales-sum-map.html')
    
    
	

    # 2.2 生成柱狀圖
    province_sales_sum_bar = (
        Bar()
            .add_xaxis(province_sales_sum.index.tolist())##['廣東', '上海', '江蘇', ]
            .add_yaxis("", list(np.ravel(province_sales_sum.values)), category_gap="50%")#[520770, 336154, 103786,]
            .set_global_opts(
            title_opts=opts.TitleOpts(title="前兩千款避孕套各省商家銷量總和地區柱狀圖"),
            yaxis_opts=opts.AxisOpts(name="總銷量"),
            xaxis_opts=opts.AxisOpts(name="地區", axislabel_opts={"rotate": 90})
        )
    )
    province_sales_sum_bar.render('province-sales-sum-bar.html')

    # 3、全國商家省份平均銷量分布
    province_sales_mean = DF_STANDARD.pivot_table(index='location', values='sales', aggfunc=np.mean)
    # 根據平均銷量排序
    province_sales_mean.sort_values('sales', inplace=True, ascending=False)
    province_sales_mean_list = [list(item) for item in
                                zip(province_sales_mean.index, np.ravel(province_sales_mean.values))]

    print(province_sales_mean_list)
	#[['山西', 1535.7931034482758], ['廣東', 804.8995363214838],]

    # 3.1 生成熱力圖
    province_sales_mean_map = (
        Map()
            .add("前兩千款避孕套商家平均銷量全國分布圖", province_sales_mean_list, "china")
            .set_global_opts(
            visualmap_opts=opts.VisualMapOpts(max_=1536),
        )
    )
    province_sales_mean_map.render('province-sales-mean-map.html')
    # 3.2 生成柱狀圖
    province_sales_mean_bar = (
        Bar()
            .add_xaxis(province_sales_mean.index.tolist())
            .add_yaxis("", list(map(int, np.ravel(province_sales_mean.values))), category_gap="50%")
            .set_global_opts(
            title_opts=opts.TitleOpts(title="前兩千款避孕套各省商家平均銷量地區柱狀圖"),
            yaxis_opts=opts.AxisOpts(name="平均銷量"),
            xaxis_opts=opts.AxisOpts(name="地區", axislabel_opts={"rotate": 90})
        )
    )
    province_sales_mean_bar.render('province-sales-mean-bar.html')
           

運作程式

if __name__ == '__main__':
    # 資料清洗
    standard_data()
    # 資料分析
    analysis_title()
    analysis_price()
    analysis_sales()
    analysis_price_sales()
    analysis_province_sales()
           

3. 函數分布

3.1 分析标題關鍵字與其他屬性的關系analysis_title_keywords()

def analysis_title_keywords(keywords_count_list, column, top_num) -> dict:
    """
    分析标題關鍵字與其他屬性的關系
    :param keywords_count_list: 關鍵字清單
    :param column: 需要分析的屬性名
    :param top_num: 截取前多少個
    :return:
    """
    # 1、擷取高頻詞,生成一個dict={'keyword1':[], 'keyword2':[],...}
    keywords_column_dict = {i[0]: [] for i in keywords_count_list}
    #keywords_count_list 詞數統計 [('情趣', 1.0), ('尿酸', 0.44688260908416977), ...]
    for row in DF_STANDARD.iterrows():
        for keyword in keywords_column_dict.keys():
            if keyword in row[1].title:
                # 2、 将标題包含關鍵字的屬性值放在清單中,dict={'keyword1':[屬性值1,屬性值2,..]}
                keywords_column_dict[keyword].append(row[1][column])
                
    # 3、 求屬性值的平均值,dict={'keyword1':平均值1, 'keyword2',平均值2}
    #print(keywords_column_dict)
    #'情趣': [10000, 15000, 150000, 30000, 6500, 4895, 3597, 1676, 25000, 103, 20000, 6000, 6000, 15000, 10000, 4296,
     #      10000, 10000, 6500, 2228, 2867, 1964, 2133, 3053, 302
    for keyword in keywords_column_dict.keys():
        keyword_column_list = keywords_column_dict[keyword]
        keywords_column_dict[keyword] = sum(keyword_column_list) / len(keyword_column_list)
        
    # 4、 根據平均值排序,從小到大
    keywords_price_dict = dict(sorted(keywords_column_dict.items(), key=lambda d: d[1]))
    #print('根據平均值排序,從小到大',sorted(keywords_column_dict.items(), key=lambda d: d[1]))
    #list [('有償', 14.597407407407411), ('帶刺', 33.16016260162596),
    
    # 5、截取平均值最高的20個關鍵字
    keywords_price_dict = {k: keywords_price_dict[k] for k in list(keywords_price_dict.keys())[-top_num:]}
    print('截取平均值最高的20個關鍵字',keywords_price_dict)
    return keywords_price_dict
           

3.2 分析商品某數值區間分布柱狀體 cut_and_sort_data()

def cut_and_sort_data(listBins, listLabels, data_list) -> dict:
    """
    統計list中的元素個數,傳回元素和count
    :param listBins: 資料切分區域
    :param listLabels: 切分後對應标簽
    :param data_list: 資料清單形式
    :return: key為元素value為count的dict
    """
    data_labels_list = pd.cut(data_list, bins=listBins, labels=listLabels, include_lowest=True)
    # 生成一個以listLabels為順序的字典,這樣就不需要後面重新排序
    #print('data_labels_list',data_labels_list)
        #0 41 - 60
        #1 41 - 60
        #2 21 - 40

    data_count = {i: 0 for i in listLabels}
    # data_count {listLabel1 : 0, listLabel2 : 0}
    # 統計結果
    for value in data_labels_list:
        # get(value, num)函數的作用是擷取字典中value對應的鍵值, num=0訓示初始值大小。
        data_count[value] = data_count.get(value) + 1
    return data_count
           

繼續閱讀