按周(星期)统计后自动生成滚动式趋势图

公司需要每周进行业务量统计汇总,连续统计几个星期的销售业绩,自动生成柱状图,直观展现出每个星期的增减变化。
每天的数据明细表,按产品ID进行记录,入库日期时间、是否已出货、销售员、业绩等级等等,大概如下表:
每天数据统计表
思路:原数据是每一天各名销售员不同产品的销售计划和实际销售的明细表,表的日期格式是“yyyymmdd 时分秒”,每一天都会有新数据更新。先把日期转换成"%Y-%m-%d",再换成周数,即哪一个日期是对应年份的第几周。不论是星期几查看数据图,都会自动汇总统计上一周及以前各周的数据。滚动地画出前8周的柱状图。
如果按销售员或省份、营业点进行筛选,则分别生成的对应的柱状图。
先看看最后的效果图。

在这里插入图片描述

考虑到几个月以后,X轴名称标注第几周不太直观,就以T-1表示上一周,T-2表示前一周,等等。
在这里插入图片描述

难点:跨年度的那一周,7天中既包括了上一年的日期,也有当年的日期,必须把每年度开始几天的日期划入了上一年的第52周进行统计,上一年的最后几天与今年的开头几天合并成一个完整的周期。
代码如下,先导入模块:

import datetime
from datetime import timedelta
from dateutil.relativedelta import * #月度推算
import pandas as pd #导入pandas库
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']   # 用黑体显示中文
plt.rcParams['axes.unicode_minus']=False     # 正常显示负号

根据查看时的当天电脑日期,生成统计周期,默认是统计8个星期的业务量。本周的业务不统计,往前计算8周,而且无论是哪一天查看结果都 是本周的前面8个星期。重点是跨年度的前后几天

#下面根据当前日期,往前推算每一日期(格式为"%Y-%m-%d")属于今年的第几周,生成列表
value19 = []#一年中的第几周
date_all=[]#建立一个空列表,将调入统计期间的周数,上面的原始数据表已经处理出来了,后面的输出不需要包括本周了
weeknum0=1#本周的0,1是上周
while weeknum0 <= 9:#设置周报的期数,默认8周
    date_week = (now+relativedelta(days = -7*weeknum0)).strftime('%W') #  每减7天对应的 第几周
    if int(date_week)==0:#判断是不是今年的第0周
        w=(now+relativedelta(days = -7*weeknum0)).strftime('%w')# 小写w是星期几,星期日=0,星期六=6                     if int(w)==0:
        if int(w)==0:
            date_week = (now+relativedelta(days = -7*weeknum0-1*7+1)).strftime('%W')#00周中的日,这一天退到周一,即合并到上一年的最后一周的周一
        else:
            date_week = (now+relativedelta(days = -7*weeknum0-1*(int(w))+1)).strftime('%W')# 00周中的星期一到星期六,这一天退到周一,即合并到上一年的最后一周的周一
        date_all.append("%s第%s周" % (str(int(year1[:-1])-1),str(date_week)))
    else:
        date_all.append("%s第%s周" % ((now+relativedelta(days = -7*weeknum0)).strftime('%Y'),str(date_week)))
    value19.append(str(date_week))
    weeknum0 +=1

由Excel导入原始数据:

#下面根据业绩统计表.xls中列名为'数据生成时间',提取日期,推算该日期(格式为"%Y-%m-%d")属于今年的第几周
data_yjc = pd.read_excel(r'D:\CF-sz5\业绩统计表.xls',sheet_name=0,header=0,dtype=object,na_rep="")
data_yjc['星期']=data_yjc.apply(lambda x: x['数据生成时间'][0:4]+'-'+x['数据生成时间'][4:6]+'-'+x['数据生成时间'][6:8], axis=1)#数据日期转换格式成"%Y-%m-%d"
data_yjc['星期1'] = data_yjc['星期'].apply(lambda x: (datetime.datetime.strptime(x ,"%Y-%m-%d").strftime("%Y"))+(datetime.datetime.strptime(x ,"%Y-%m-%d").strftime("%W")))#年份+周数
data_yjc['星期5'] = data_yjc['星期1'].apply(lambda x: str(int(x[0:4])-1)+'52')#用于判断是不是每年的第0周,就转变成上一年的第52周
data_yjc['星期汇总'] = np.where(data_yjc['星期1'].astype(str).str[4:]=='00',data_yjc['星期5'],data_yjc['星期1'])#把跨年的那一周,周数为零的替换成上一年最后一周
data_yjc["汇总1"] =['%s' % i for i in data_yjc["星期汇总"].astype(str).str[0:4]]# 年份数,取data_yjc["星期汇总"]的前4位
data_yjc["汇总2"] =['00%s' % i for i in data_yjc["星期汇总"].astype(str).str[4:]]#周数,可能是一位数,也可能是2位数,前面添加2个零,
data_yjc["汇总3"] =['第%s周' % i for i in data_yjc["汇总2"].astype(str).str[-2:]]#周数,把前面添加2个零的周数取倒数2位数
data_yjc["月份汇总"]=data_yjc["汇总1"]+data_yjc["汇总3"]#按星期(数据生成日期)计算第几周
#下面汇总统计,每条明细是一件产品,使用count计数
data_yjc=data_yjc[data_yjc["月份汇总"].isin(date_all[:])]#筛选出data_yjc中周数包括date_all的明细表
df8_1=pd.pivot_table(data_yjc,index=[u'月份汇总'],values=['售销数量'],aggfunc='count')
df8_2=pd.pivot_table(data_yjc,index=[u'月份汇总'],values=['售销任务'],aggfunc='count')
df8_8= pd.concat([df8_2,df8_1],axis=1,join_axes=[df8_1.index])#左联接表

生成X轴和Y轴的数据,列表形式,然后自动生成画图

#下面将每周的售销任务和销量换算成前几周(表示为"T-1周","T-2周","T-3周"等),本周不统计
print("电脑推算的周在这里:")#每一周是:星期一至星期日,分别对应星期值是1,2...5,6,0
print(date_all)
T0 = ["T-1周","T-2周","T-3周","T-4周","T-5周","T-6周","T-7周","T-8周"] #设置一个8周的列表
T0 = date_all #以实际年份第几周为期数
T = T0[:zhou_Num-1][::-1]#将zhou_Num恢复到用户录入的期数,[::-1]为倒序                                         
df8_0 = pd.DataFrame(date_all[::-1],columns=['汇总'])                                          
df_zh = pd.concat([df8_0, pd.DataFrame(T,columns=['月份汇总'])],axis=1)#用T替代                                          
df_zh.set_index(['汇总'], inplace = True)
df8_zh= pd.concat([df_zh,df8_8],axis=1,join_axes=[df_zh.index])#                                          
df=df8_zh.where(df8_zh.notnull(),0)#

#下面将每周的售销任务和销量赋值画图的坐标值
num_list1 = [ i for i in list(df['销售任务'])]
num_list2 = [ i for i in list(df['售销数量'])]                                    
label_list0 = [ i for i in list(df.index)]

#下面画图(略)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值