商铺数据加载及存储

商铺数据

要求:

  1. 成功读取“商铺数据.csv”文件
  2. 解析数据,存为list
  3. 数据清洗:

    • comment,price两个字段清洗成数字
    • 清除字段缺失的数据
    • commentlist拆分成三个字段,并且清洗成数字
  4. 结果存为.csv文件

# 1.导入数据
f=open('商铺数据.csv','r',encoding='utf-8')
#查看前6行数据函数
def data(x):
    if x==all:
        for line in f.readlines()[:6] :#查看前5行数据
            print(line.split(','))# 按,拆分
    else:
        for line in f.readlines()[:6] :
            print(line.split(',')[x])
    f.seek(0,0)
data(all)
['\ufeffclassify', 'name', 'comment', 'star', 'price', 'address', 'commentlist\n']
['美食', '望蓉城老坛酸菜鱼(合生汇店)', '我要点评', '该商户暂无星级', '人均                                        ¥125', '翔殷路1099号合生汇5F', '口味8.3                                环境8.4                                服务8.5\n']
['美食', '泰国街边料理', '74                    条点评', '准四星商户', '人均                                        ¥48', '黄兴路合生汇B2美食集市内', '口味7.4                                环境7.6                                服务7.4\n']
['美食', '壹面如故(苏宁生活广场店)', '265                    条点评', '准四星商户', '人均                                        ¥21', '邯郸路585号苏宁生活广场B1层', '口味7.0                                环境7.2                                服务7.2\n']
['美食', '鮨谷•Aburiya(合生汇店)', '2748                    条点评', '准五星商户', '人均                                        ¥142', '翔殷路1099号合生广场5楼23、28铺位', '口味8.9                                环境8.5                                服务8.4\n']
['美食', '我们的烤肉我们的馕', '5                    条点评', '准四星商户', '人均                                    -', '邯郸路399-D3号', '口味7.5                                环境6.8                                服务7.5\n']

清洗数据

商铺数据.csv

清洗评论数量数据

f.seek(0,0)
print('---原始数据预览---')
data(2)#查看评论数据

#定义清洗数据函数
import re

def comment_number(s):
    if '我要点评' in s:
        return '无数据'
    else:
        return re.findall(r'\d+',s)

print('---清洗完数据预览---')

for line in f.readlines()[:6] :
        cm_n=comment_number(line.split(',')[2])
        print(cm_n)
---原始数据预览---
comment
我要点评
74                    条点评
265                    条点评
2748                    条点评
5                    条点评
---清洗完数据预览---
[]
无数据
['74']
['265']
['2748']
['5']

清洗价格数据

f.seek(0,0)

print('---原始数据预览---')
data(4)

def pri(s):
    if '-' in s:
        return '无数据'
    else:
        return re.findall(r'\d+',s)

print('---清洗完数据预览---')

for line in f.readlines()[:6] :
        pr=pri(line.split(',')[4])
        print(pr)
---原始数据预览---
price
人均                                        ¥125
人均                                        ¥48
人均                                        ¥21
人均                                        ¥142
人均                                    -
---清洗完数据预览---
[]
['125']
['48']
['21']
['142']
无数据

清洗评论数据

f.seek(0,0)

print('---原始数据预览---')
data(-1)

def comment(s):
    if len(s)<3:
        return '无数据'
    else:
        return re.findall(r'\d+\.\d',s)#提取小数


print('---清洗完数据预览---')

for line in f.readlines()[:6] :
        cm=comment(line.split(',')[-1])
        print(cm)
---原始数据预览---
commentlist

口味8.3                                环境8.4                                服务8.5

口味7.4                                环境7.6                                服务7.4

口味7.0                                环境7.2                                服务7.2

口味8.9                                环境8.5                                服务8.4

口味7.5                                环境6.8                                服务7.5

---清洗完数据预览---
[]
['8.3', '8.4', '8.5']
['7.4', '7.6', '7.4']
['7.0', '7.2', '7.2']
['8.9', '8.5', '8.4']
['7.5', '6.8', '7.5']

汇总数据

#数据清洗
import csv
csvfile=open('清洗完数据.csv','w')
writer = csv.writer(csvfile)
writer.writerow(['classify','name','comment','star','price','address','quality','environment','service'])

f.seek(0,0)

for line in f.readlines()[1:10] :#删除第一个数据
    s=line.split(',')   
    classify=s[0]
    name=s[1]
    comment_1=comment_number(s[2])[0]#获取列表下数字
    star=s[3]
    price=pri(s[4])[0]
    address=s[5]
    quality=comment(s[-1])[0]
    environment=comment(s[-1])[1]
    service=comment(s[-1])[2]
#预览查看    
    print(classify,name,comment_1,star,price,address,quality,environment,service)
    
#删除缺失数据   
    if '无数据'not in [classify,name,comment_1,star,price,address,quality,environment,service]:
        writer.writerow([classify,name,comment_1,star,price,address,quality,environment,service])
        
csvfile.close()
f.close()
美食 望蓉城老坛酸菜鱼(合生汇店) 无 该商户暂无星级 125 翔殷路1099号合生汇5F 8.3 8.4 8.5
美食 泰国街边料理 74 准四星商户 48 黄兴路合生汇B2美食集市内 7.4 7.6 7.4
美食 壹面如故(苏宁生活广场店) 265 准四星商户 21 邯郸路585号苏宁生活广场B1层 7.0 7.2 7.2
美食 鮨谷•Aburiya(合生汇店) 2748 准五星商户 142 翔殷路1099号合生广场5楼23、28铺位 8.9 8.5 8.4
美食 我们的烤肉我们的馕 5 准四星商户 无 邯郸路399-D3号 7.5 6.8 7.5
美食 麦当劳(万达店) 785 准四星商户 24 邯郸路600号万达商业广场B1楼A05号铺 7.4 7.2 7.2
美食 蒸年青STEAMYOUNG(百联又一城购物中心店) 3779 准五星商户 70 淞沪路8号百联又一城购物中心7层 8.6 8.6 8.6
美食 丸来玩趣(百联又一城购物中心店) 458 准四星商户 14 淞沪路8号百联又一城购物中心B1层 7.0 6.5 6.5
美食 韩国雪冰(合生汇店) 1280 四星商户 47 翔殷路1099号合生汇4F 7.7 7.5 7.6

代码汇总

# 1.导入数据
f=open('商铺数据.csv','r',encoding='utf-8')
#2. 定义函数
import re

def comment_number(s):
    if '我要点评' in s:
        return '无数据'
    else:
        return re.findall(r'\d+',s)
    
def pri(s):
    if '-' in s:
        return '无数据'
    else:
        return re.findall(r'\d+',s)
    
def comment(s):
    if len(s)<3:
        return '无数据'
    else:
        return re.findall(r'\d+\.\d',s)#提取小数
    
# 3.计算清洗数据&导出csv

import csv
csvfile=open('清洗完数据.csv','w')
writer = csv.writer(csvfile)
writer.writerow(['classify','name','comment','star','price','address','quality','environment','service'])

f.seek(0,0)
n=0 #计数变量
for line in f.readlines()[1:] :#删除第一个数据
    s=line.split(',')   
    classify=s[0]
    name=s[1]
    comment_1=comment_number(s[2])[0]#获取列表下数字
    star=s[3]
    price=pri(s[4])[0]
    address=s[5]
    quality=comment(s[-1])[0]
    environment=comment(s[-1])[1]
    service=comment(s[-1])[2]
    
#删除缺失数据   
    if '无数据'not in [classify,name,comment_1,star,price,address,quality,environment,service]:
        n+=1
        writer.writerow([classify,name,comment_1,star,price,address,quality,environment,service])
        
print('导出成功,合计'+str(n)+'条数据')
csvfile.close()
f.close()
导出成功,合计1265条数据

清洗完数据

2020/02/21 posted in  项目

当当图书爬虫

# 爬取当当网图书
import requests
from pyquery import PyQuery
import csv
import time

class DDSider(object):
    def __init__(self,key):
        self.key = key
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'
        }
        self.base_url = 'http://search.dangdang.com/?key='+key+'&act=input&page_index={}'
    # 获取界面内容 
    def get_pageInfo(self):
        
        num_page = 0
        while True:
            num_page += 1 
            page_url = self.base_url.format(num_page)
            res = requests.get(page_url,headers=self.headers)
#             print(res.content.decode('GBK'))
            
            # 解析
            self.parse_pageInfo(res.content.decode('GBK'))
            time.sleep(1)
            if num_page == 1:
                break
                
    def parse_pageInfo(self,html):
        doc = PyQuery(html)
        
        book_ul = doc('#component_59 li').items()
        
        for one_li in book_ul:
#             print(one_li)
            # 图片的链接
            if one_li('.pic img').attr('data-original'):
                img_url = one_li('.pic img').attr('data-original')
                
            else:
                img_url = one_li('.pic img').attr('src')
            
            # 标题
            title = one_li('.name a').attr('title')

            # 价格
            price = one_li('.price .search_now_price').text()

            # 获取评价数
            comments = one_li('.search_star_line .search_comment_num').text()
            
            #search_star_black
#             stars = one_li('.search_star_black span').attr('style').split(':')[-1].strip('%;')
            stars = float(one_li('.search_star_black span').attr('style').split(':')[-1].strip('%;'))/20
#             print(stars)

if __name__ == "__main__":
    dd = DDSider('python')
    dd.get_pageInfo()
5.0
4.5
4.5
4.5
4.5
4.5
4.5
5.0
4.5
4.5
5.0
4.5
5.0
3.0
4.5
4.5
5.0
5.0
5.0
4.5
5.0
4.5
4.5
4.5
4.5
0.0
4.5
4.5
4.5
4.0
4.5
5.0
4.0
5.0
4.5
4.5
4.5
5.0
3.0
5.0
5.0
5.0
5.0
4.5
4.5
0.0
5.0
5.0
4.5
5.0
4.0
5.0
4.5
5.0
4.5
0.5
4.5
4.5
4.0
5.0
import time
import requests
import json
# 时间戳: 1970-01-01 00:00:00 到当前时间的的秒数(10位数)或者是毫秒数(13位)
# timestamp = 1559223244110
# timearray = time.localtime(float(timestamp/1000))
# tt = time.strftime('%Y--%m--%d %H:%M:%S',timearray)
# print(tt)

# 把当前时间转成时间戳的格式

# timestamp = int(time.time())*1000
# timearray = time.localtime(float(timestamp/1000))
# tt = time.strftime('%Y--%m--%d %H:%M:%S',timearray)
# print(tt)
# 动态界面的爬取
base_url = 'https://careers.tencent.com/tencentcareer/api/post/Query?timestamp={}&keyword=Python&pageIndex=1&pageSize=10&language=zh-cn&area=cn'

timestamp = int(time.time())*1000
headers = {
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'
        }
url = base_url.format(timestamp)
print(url)

res = requests.get(url=url,headers=headers)
# print(res.content.decode('utf-8'))

# 将数据转化成Python对象
conntent_dict = json.loads(res.content.decode('utf-8'))

Data_dict = conntent_dict['Data']
# posts_list 里面存的就是我们想要的数据
posts_list = Data_dict['Posts']

# 拿到每一条数据
for value_dict in posts_list:
    
    RecruitPostName = value_dict['RecruitPostName']
    print(RecruitPostName)
    LastUpdateTime = value_dict['LastUpdateTime']
    print(LastUpdateTime)





https://careers.tencent.com/tencentcareer/api/post/Query?timestamp=1559224906000&keyword=Python&pageIndex=1&pageSize=10&language=zh-cn&area=cn
25923-监控系统开发工程师(Python)(深圳)
2019年05月30日
31504-AI机器人后台开发工程师(python)
2019年05月29日
CSIG16-python高级研发工程师
2019年05月25日
TME-腾讯音乐python开发工程师
2019年05月17日
25923-Python高级工程师(上海)
2019年04月19日
25923-Python高级工程师(深圳)
2019年04月19日
25923-数据分析平台开发工程师(Python)(深圳)
2019年03月21日
PCG04-安全测试专家(后台服务/客户端)
2019年05月30日
30359-大数据高级开发工程师(深圳)
2019年05月30日
31504-腾讯云监控高级运维工程师
2019年05月30日
2020/02/21 posted in  项目

餐饮业日销售情况表

理解数据

-bil

-orde

-shop
数据来自三个csv文件,包含字段如下:

单号详细: Bill表

字段名 字段描述
billdate 日期
billnumber 单号
shopname 店名
billdiscount 会员折扣
paytime 付费时间
tablenumber 桌号
peoplecount 来店人数

点菜明细: OrderDetail表

字段名 字段描述
billnumber 单号
detail 菜品明细
pay 消费金额

店面情况: ShopDetail表

字段名 字段描述
ShopName 店名
twotable 二人台数
threetable 三人台数
fourtable 四人及以上台数
alltable 总台数

提出问题

根据餐饮业日销售情况详细,拟定从下几个维度建立数据指标。

图中设计KPI指标情况具体见下表:

KPI 描述
销售金额 当日店铺实际收入
折扣额 占销售总额的10%-20%
折扣率 10%-20%
台数 店铺总台(桌)数
翻台率 当日店铺每张桌子被使用的平均次数
单均消费 当日店铺所有缴费单的平均金额
座位数 店铺实际拥有座位的数量
上座率 当日店铺每个座位被使用的平均次数
人均消费 当日到店每个人的平均消费金额(销售总额/客流量)
销售KPI 每家店的销售金额与所有店的总平均金额的比

模型构建

创建单汇总金额表(OrderGroup)

以orderdetail表的billnumber字段为汇总依据,求出每条billnumber下pay的加总值。

create table ordergroup(    select billnumber ,sum(pay) as pay from orderdetail    group by billnumber);

OrderGroup

字段名 字段描述
billnumber 单号
sum(pay) 金额

创建新单号详细表(NewBill)

以billnumber为关键字段关联两表,将OrderGroup表中的pay字段合并到Bill表中,并使用pay与billdiscount字段计算出折扣金额。

create table newbill (    select bill.*, pay,billdiscount * pay as rebate from bill     left join ordergroup on bill.billnumber = ordergroup.billnumber);

NewBill

字段名 字段描述
billdate 日期
billnumber 单号
shopname 店名
billdiscount 会员折扣
paytime 付费时间
tablenumber 桌号
peoplecount 来店人数
pay 金额
rebate 折扣金额

创建新店面情况表(NewShopDetail)

在原有shopdetail表字段基础上计算并添加allseats字段.allseats = twotable _ 2 + three _ 3 + fourtable * 6

create table newshopdetail(    select *, (twotable*2+threetable*3+fourtable*4) as allseats from shopdetail);

New  ShopDetail

字段名 字段描述
ShopName 店名
twotable 二人台数
threetable 三人台数
fourtable 四人及以上台数
alltable 总台数
allseats 总座位数

创建新点菜明细表(NewOrderDetail)

以billnumber为关键字段关联两表,并用Bill表中的shopname与OrderDetail表中的所有字段组成新表

create table neworderdetail(    select orderdetail.*,bill.shopname from orderdetail left join bill on bill.billnumber= orderdetail.billnumber);

NewOrderDetail

字段名 字段描述
billnumber 单号
detail 菜品明细
pay 消费金额
shopname 店名

创建店汇总信息表(ShopTotal)

以shopname字段为关键字段关联两表,并以shopname字段为汇总条件建立表格。

create table shoptotal(    select newbill.shopname as 店名,    count(newbill.billnumber) as 单数,    sum(newbill.peoplecount) as 人数,    sum(newbill.rebate) as 折扣总金额,    sum(newbill.pay) as 店汇总金额,    sum(newbill.pay)/count(newbill.billnumber) as 单均消费,    sum(newbill.pay)/sum(newbill.peoplecount) as 人均消费,    newshopdetail.alltable as 总台数,    newshopdetail.allseats as 总座位数,    count(newbill.billnumber) /newshopdetail.alltable as 翻台率,    sum(newbill.peoplecount)/newshopdetail.allseats as 上座率,    sum(newbill.rebate)/sum(newbill.pay) as 折扣率    from newbill left join newshopdetail on newbill.shopname = newshopdetail.shopname    group by newbill.shopname);

ShopTotal

字段名 字段描述
店名 b.shopname
单数 b.billnumber的计数
人数 b.peoplecount的加总
折扣总金额 b.rebate的加总
店汇总金额 b.pay的加总
单均消费 b.pay的合计值/b.billnumber的计数值
人均消费 b.pay的合计值/b.peoplecount的合计值
总台数 s.alltable
总座位数 s.allseats
翻台率 b.billnumber的计数值/s.alltable
上座率 b.peoplecount的合计值/s.allseats
折扣率 b.rebate的合计值/b.pay的合计值

可视化报表展示

将结果shoptotal,neworderdetail,newbill导入power BI,利用shoptotal.店面,newbill.shopname,neworderdetail.shopname 关联三个表格。制作可视化报表。

可视报表包括常见KPI指标情况,方面阅读者查看日常达成额;店面平均达成情况,结合其他店面平均确认店面销售水平;时间维度下销售额与销售数量情况,方便拟定用餐高低峰期情况;同时有各类菜品销量,销售金额占比及明细表,方便配比菜品,拟定价格。


newbil

neworderdetail

shoptota

2020/02/21 posted in  项目