一、需求
针对Amazon销售后台导出的销售记录(Excel形式),将其划分成各产品的销量-时间图和销量-分布图。
Excel格式如下所示:
原始数据表
二、思路
2.1 销量时间图
按产品(sku列)筛选原始数据表,统计各个产品在不同时间(date/time列)的销量(quantity列),统计结果存入以该产品名命名的excel中。各产品统计excel形式如下:
各产品销量 - 时间统计表
再以各产品销量 - 时间统计表为输入数据,批量绘制各产品的销量时间图。
2.2 销量分布图
步骤同销量时间图,按产品(sku列)筛选原始数据表,统计各个产品在不同地区(date/time列)的销量(quantity列),统计结果存入以该产品名命名的excel中。各产品统计excel形式如下:
各产品销量 - 地区统计表
再以各产品销量 - 地区统计表为输入数据,批量绘制各产品的销量分布图。
三、Python代码实现——销量时间图
3.1 批量将原始数据表处理成多张销量-时间excel(按产品分)
# 创建目录
import os
def mkdir(savepath1):
isExists=os.path.exists(savepath1)
if not isExists:
os.makedirs(savepath1)
print(savepath1+' 创建成功')
return True
else:
print(savepath1+' 目录已存在')
return False
import pandas as pd
import numpy as np
import openpyxl
from datetime import datetime
def generate_sales_excel_for_timeline(ori_file, savepath):
savepath1 = savepath + "/销量文件-时间"
mkdir(savepath1)
df = pd.read_excel(ori_file, sheet_name = 0)
dates = df['date/time'].tolist()
skus = df['sku'].tolist()
dates1 = []
for date in dates: # 处理date字符串,只保留年月日信息
date1 = date[0:-15] # 针对所给的日期格式,去掉后面的时分秒
date1 = date1.rstrip()
dates1.append(date1)
df.loc[:,'date/time'] = dates1 # 替换原来DataFrame中'date/time'的值
print(df)
duplicated_dates0 = list(set(dates1)) # 日期去重
arr = np.array(duplicated_dates0)
# 将str格式的日期转换成date格式,排序,再转换成str格式
duplicated_dates = arr[np.argsort([datetime.strptime(i, '%b %d, %Y') for i in duplicated_dates0])].tolist()
print(duplicated_dates)
duplicated_skus = list(set(skus)) # 商品种类去重
num_sku = len(duplicated_skus) # 商品种类数
print(duplicated_skus)
k = 1
for duplicated_sku in duplicated_skus:
list_sales = [] # 用于存放每一种产品的各日期销量
for duplicated_date in duplicated_dates:
df_sku_date = df.loc[(df['date/time'] == duplicated_date)&(df['sku'] == duplicated_sku)]
sale = df_sku_date['quantity'].sum() # 循环,筛选出每一种产品每一个日期的记录,对销量求和
list_sales.append(sale)
wb = openpyxl.Workbook() # 每一种产品生成一张excel表格
ws = wb['Sheet']
ws.title = duplicated_sku
ws.cell(1,1).value = 'date'
ws.cell(1,2).value = 'sale'
for i in range(len(duplicated_dates)): # 对应的单元格内填入内容
ws.cell(i+2 ,1).value = duplicated_dates[i]
ws.cell(i+2 ,2).value = list_sales[i]
wb.save(savepath1 + "/" + duplicated_sku + ".xlsx")
print('正在生成第%d个excel文件'%(k))
print('进度:(%d / %d)'%(k, num_sku))
k += 1
list_sales_total = [] # 同理,生成每一个日期的所有产品汇总销量文件Total.xlsx
for duplicated_date in duplicated_dates:
df_date = df.loc[df['date/time'] == duplicated_date]
sale_total = df_date['quantity'].sum()
list_sales_total.append(sale_total)
wb = openpyxl.Workbook()
ws = wb['Sheet']
ws.title = 'Total'
ws.cell(1,1).value = 'date'
ws.cell(1,2).value = 'sale'
for i in range(len(duplicated_dates)):
ws.cell(i+2 ,1).value = duplicated_dates[i]
ws.cell(i+2 ,2).value = list_sales_total[i]
wb.save(savepath1 + "/Total.xlsx")
print('正在生成Total文件')
print('进度:(1 / 1)')
print('所有销量-时间文件已生成完毕!')
if __name__ == "__main__":
ori_file='D:/原始订单数据.xlsx'
savepath = 'D:/时间图'
generate_sales_excel_for_timeline(ori_file, savepath)
运行结果:
批量生成的销量 - 时间统计表
某产品销量 - 时间统计表
3.2 批量绘制销量时间图
import pyecharts.options as opts
from pyecharts.charts import Line, Grid
import os
import openpyxl
import pandas as pd
# 绘制单张销量时间图
def draw_USA_timeline(df, sheet_title, savepath):
savepath1 = savepath + '/销量时间图'
mkdir(savepath1)
timeData = df['date'].tolist()
salesData = df['sale'].tolist()
line = (
Line(init_opts=opts.InitOpts(width = "1200px", height= "600px"))
.add_xaxis(timeData) # 横坐标数据:时间列表
.add_yaxis(
sheet_title, # 系列名
salesData , # 纵坐标数据:销量列表
is_smooth=True, # 平滑效果
label_opts=opts.LabelOpts(is_show=False),
symbol_size=8,
linestyle_opts=opts.LineStyleOpts(width=1.5),
)
.set_global_opts(
title_opts=opts.TitleOpts(
title="销量时间图", subtitle="数据统计自" + timeData[0]
),
xaxis_opts=opts.AxisOpts(
axistick_opts=opts.AxisTickOpts(is_align_with_label=True),
is_scale=False,
boundary_gap=False,
),
tooltip_opts=opts.TooltipOpts(trigger="axis"), # 纵向有条线,更容易选中
axispointer_opts=opts.AxisPointerOpts( # 横向加线,会选中与鼠标所在地具有相同y值的点,以及对应的y值
is_show=True, link=[{"xAxisIndex": "all"}]
),
datazoom_opts=[ # 区域缩放项
opts.DataZoomOpts(
is_show=True,
is_realtime=True, # 拖动过程中实时显示
)
],
yaxis_opts=opts.AxisOpts(name="销售量(个)", name_location="center", name_gap=55),
toolbox_opts=opts.ToolboxOpts( # 工具箱设置
is_show=True,
feature={
"dataZoom": {"yAxisIndex": "none"}, # 区域缩放按钮
"restore": {}, # 撤销
"saveAsImage": {}, # 保存为图片
},
),
)
.render(savepath1 + '/' + sheet_title + '.html') # 保存为html格式文件
)
# 批量绘制销量时间图
def draw_all_USA_timeline(path, savepath):
filenames = os.listdir(path) # 获取文件夹下所有文件名
for i, filename in enumerate(filenames):
if i==0:
iSpecialFile=i+1
sFileName=filename # 获取当前文件名
print('==================第%s个文件========================='%(i+1))
print('文件名:%s'%(filename))
wb = openpyxl.load_workbook(path+'/'+filename)
sheets = wb.sheetnames # 获取当前workbook中所有的表格
for j in range(len(sheets)): # 循环遍历所有sheet
sheet = wb[sheets[j]]
print('第' + str(j + 1) + '个sheet Name: ' + sheet.title)
df = pd.read_excel(path + '/' + filename,sheet_name=j)
draw_USA_timeline(df,sheet.title, savepath) # 每一张sheet绘制一份html地图
print('--------------------------------结束--------------------------------')
print('\n')
if __name__ == "__main__":
path = 'D:/时间图/销量文件-时间'
savepath = 'D:/时间图/销售时间图'
draw_all_USA_timeline(path, savepath)
运行结果:
批量生成的销量时间图
某产品销量时间图
四、Python代码实现——销量分布图(美国各州)
4.1 批量将原始数据表处理成多张销量-地区excel(按产品分)
import os
def mkdir(savepath1):
isExists=os.path.exists(savepath1)
if not isExists:
os.makedirs(savepath1)
print(savepath1+' 创建成功')
return True
else:
print(savepath1+' 目录已存在')
return False
def generate_sales_excel_for_map(ori_file, savepath):
savepath1= savepath + '/销量文件-地图'
mkdir(savepath1)
df = pd.read_excel(ori_file, sheet_name=0)
skus = df['sku'].tolist()
states = df['order state'].tolist()
states1 = []
for state in states: # 替换DataFrame中'order state'的值,使其全大写
state1 = state.upper()
states1.append(state1)
df.loc[:,'order state'] = states1
duplicated_states = [ # 美国所有州
'AL',
'AK',
'AZ',
'AR',
'CA',
'CO',
'CT',
'DE',
'FL',
'GA',
'HI',
'ID',
'IL',
'IN',
'IA',
'KS',
'KY',
'LA',
'ME',
'MD',
'MA',
'MI',
'MN',
'MS',
'MO',
'MT',
'NE',
'NV',
'NH',
'NJ',
'NM',
'NY',
'NC',
'ND',
'OH',
'OK',
'OR',
'PA',
'PR',
'RI',
'SC',
'SD',
'TN',
'TX',
'UT',
'VT',
'VA',
'WA',
'WV',
'WI',
'WY',
'DC'
]
duplicated_skus = list(set(skus)) # 商品种类去重
num_sku = len(duplicated_skus) # 商品种类数
print(duplicated_skus)
k = 1
for duplicated_sku in duplicated_skus:
list_sales = [] # 用于存放每一种产品的各地区销量
for duplicated_state in duplicated_states:
df_sku_state = df.loc[(df['sku'] == duplicated_sku)&(df['order state'] == duplicated_state)]
sale = df_sku_state['quantity'].sum() # 循环,筛选出每一种产品每一个州的记录,对销量求和
list_sales.append(sale)
wb = openpyxl.Workbook() # 每一种产品生成一张excel表格
ws = wb['Sheet']
ws.title = duplicated_sku
ws.cell(1,1).value = 'state'
ws.cell(1,2).value = 'sale'
for i in range(len(duplicated_states)):
ws.cell(i+2 ,1).value = duplicated_states[i]
ws.cell(i+2 ,2).value = list_sales[i]
wb.save(savepath1 + "/" + duplicated_sku + ".xlsx")
print('正在生成第%d个excel文件'%(k))
print('进度:(%d / %d)'%(k, num_sku))
k += 1
list_sales_total = [] # 同理,生成所有产品每一个日期的销量文件Total.xlsx
for duplicated_state in duplicated_states:
df_state = df.loc[df['order state'] == duplicated_state]
sale_total = df_state['quantity'].sum()
list_sales_total.append(sale_total)
wb = openpyxl.Workbook()
ws = wb['Sheet']
ws.title = 'Total'
ws.cell(1,1).value = 'state'
ws.cell(1,2).value = 'sale'
for i in range(len(duplicated_states)):
ws.cell(i+2 ,1).value = duplicated_states[i]
ws.cell(i+2 ,2).value = list_sales_total[i]
wb.save(savepath1 + "/Total.xlsx")
print('正在生成Total文件')
print('进度:(1 / 1)')
print('所有销量-地区文件已生成完毕!')
if __name__ == "__main__":
ori_file='D:/原始订单数据.xlsx'
savepath = 'D:/分布图'
generate_sales_excel_for_timeline(ori_file, savepath)
运行结果:
批量生成的销量 - 地区统计表
某产品销量 - 地区统计表
4.2 批量绘制销量分布图
# 绘制美国销量图
def draw_USA_distribution(df, sheet_title, savepath):
fig = go.Figure(
go.Choropleth(
locations=df['state'], # 设置位置,各州的编号(缩写)
z = df['sale'].astype(float), # 设置填充色数据
locationmode = 'USA-states', # 设置国家名称
colorscale = 'Reds', # 图例颜色
colorbar_title = "销量", # 图例标题
))
fig.update_layout(
title_text = sheet_title + '美国地区销量', # 地图标题
geo_scope='usa', # 设置地图的范围为美国
#scope可选有"world","usa","europe","asia","africa","north america","south america"
)
# 将地图导出为html文件
fig.write_html(savepath + '/' + sheet_title + ".html")
# 批量绘制销量分布图
def draw_all_USA_distribution(path, savepath):
filenames = os.listdir(path) # 获取文件夹下所有文件名
savepath1 = savepath + '/销量分布图'
mkdir(savepath1)
for i, filename in enumerate(filenames):
if i==0:
iSpecialFile=i+1
sFileName=filename # 获取当前文件名
print('==================第%s个文件========================='%(i+1))
print('文件名:%s'%(filename))
wb = openpyxl.load_workbook(path+'/'+filename)
sheets = wb.sheetnames # 获取当前workbook中所有的表格
for j in range(len(sheets)): # 循环遍历所有sheet
sheet = wb[sheets[j]]
print('第' + str(j + 1) + '个sheet Name: ' + sheet.title)
df = pd.read_excel(path + '/' + filename,sheet_name=j)
draw_USA_distribution(df,sheet.title, savepath1) # 每一张sheet绘制一份html地图
print('--------------------------------结束--------------------------------')
print('\n')
if __name__ == "__main__":
path = 'D:/分布图/销量文件-地图'
savepath = 'D:/分布图/销售分布图'
draw_all_USA_timeline(path, savepath)
运行结果:
批量生成的销量分布图
某产品销量分布图