文章目錄
- 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())
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TP31keRpmTwMmeNBDOsJGcohVYsR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLwMDO3UTMxADM5ETOwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
代碼如下:
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…)
2.3 标題高頻關鍵字與平均銷量關系
2.4 标題高頻關鍵字與平均售價關系
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')
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')
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')
3.3 全國商家數量分布
3.4 省份與總銷量的分布
3.5 全國商家省份平均銷量分布
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