python 爬虫 第三周:数据统计和分析

课前

安装网页编译器 Jupyter Notebook

pip install Jupyter

安装完成之后

jupyter notebook 显示本地python即可

安装数据可视化库highchart

pip install charts

在jupyter notebook跳转后,点击new python3

在新页面输入 import charts

点击cell run运行

---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-5-088ca165cfd3> in <module>
----> 1 import charts

d:\zz\pycharmprojects\test\venv\lib\site-packages\charts\__init__.py in <module>
      3 __version__ = '0.4.6'
      4 
----> 5 from plot import plot, plotasync, line, area, spline, pie
      6 from server import run_server
      7 

ModuleNotFoundError: No module named 'plot'

1)需要第一步找到charts的目录

import sys 

print(sys.path)

其中找到site-packages的路径 

'd:\\zz\\pycharmprojects\\test\\venv\\lib\\site-packages\\setuptools-40.8.0-py3.7.egg'

D:\zz\PycharmProjects\test\venv\Lib\site-packages

找到charts,

2)替换charts文件,文件在github里面

一、如何让数据说话,

麦当劳卖25种产品 汉堡包80%销量 其他20%

砍掉16样产品,降低汉堡包价格

1、提出正确的问题

有多少家庭主妇购买黄豆罐头《科学的广告 我的广告生涯》

6% 自己需要16个小时烤制 费时费力,男人更喜欢吃,罐头黄豆更容易好吃

汽车潜在用户调制鸡尾酒的能力《商业冒险》

福特新车型,和客户主题没有关系,

正确的提问能解释现象,错误的提问却强行关联无关的事物

facebook会让选择3*3*5中方案寻找45中方案

正确的提问是验证假设,错误的提问证明自己是对的

豌豆荚的机型分布数据 安卓

P2P的羊毛党数据

正确的提供是探索昂想,错误的提问是没有提出问题

解释现象、验证假设、探索方向

2、通过数据论证寻找答案

对比、细分、溯源

横向与其他人对比,纵向和自己对比

销售额=日活跃*购买转化率*客单价

日志还原场景,

3、解读数据回单问题

数据会说话,数据会说谎

支付宝代缴水电费,周期性的,数据不会错,都是认错

样本问题,样本是存在偏差的

因果关联错误

忽略前提

案例:

1、2015年互联网融资情况到底怎么样?

2、it桔子有2w家融资公司,对比,2015 VS 2014

细分 思维导图细分 什么公司获得融资(融资公司数量、地域、行业对比,获得融资比例)

,融了多少(阶段及金额,哪些行业地域公司最多),

谁投资的(投资数量分布),哪些公司没有获得(行业地域分布、成立时间、现在阶段)

溯源

3、样本偏差

二、 开始做简单的图表

1、整理清洗数据

2、更新数据库

3、数据的可视化

jupyste在线的编译器 回车是换行,shift+回车则是执行 双击折叠 单击打开 已有cell可以再次编辑

new python3 

import pymongo
from string import punctuation
# 检测字符

client = pymongo.MongoClient('127.0.0.1', 27017)
#认证
db_auth = client.admin
db_auth.authenticate("root", "root")

ceshi = client['ceshi']
item_info = ceshi['item_info']

for i in item_info.find().limit(300):
    # print(i['area'])
    # 按照原理area要是list的格式
    if i['area']:
        area = [i for i in i['area'] if i not in punctuation]
        #解析式 第一个i整体,后面是一个整体
    else:
        area = ['不明']
    print(area)

# 键值对应列表,抓取的时候有'-'
# data=None 默认是为由none的

2更新数据库

db.collection.update()

update(?,?)

第一个那个文件,第二个怎么改

{id:1,name:0,info:3}

update({id:1},{$set:{name:2})

set: position sort slice each push pushAll

pull pullAll pop set addToSet currentDate

max min unset setOnInsert rename mul inc

修改之前备份数据

进入mongo shell

show dbs展示所有数据库

use ceshi

show tables

复制开始 先创建空表,db.createCollection('item_infoY')

db.item_info.copyTo['item_infoY']

    item_info.update({'_id': i['_id']}, {'$set':{'area':area}})

# 键值对应列表,抓取的时候有'-'
# data=None 默认是为由none的
for i in item_info.find().limit(300):
     print(i['area'])

3、数据可视化图表

series = [{'name':'OS X','data':[11],'type':'column'},
          {'name':'ubuntu','data':[8],'type':'column'},
          {'name':'windows','data':[12],'type':'column'},
          {'name':'others','data':[29],'type':'column'}]
series2 = [{'name':'John','data':[5],'type':'column'},
           {'name':'John','data':[5],'type':'column'}]
charts.plot(series, show='inline', options=dict(title=dict(text='charts are anesome!!!')))

如果不显示图片也不报错,那么把浏览器关了重启即可

 data必须是数值,

www.highcharts.com/demo

4、为数据统计项调整数据结构

area_list = []
for i in item_info.find():
    area_list.append(i['area'][0]) # 排除大区
area_index = list(set(area_list)) # set是去重的
print(area_index)

post_times = []
for index in area_index:
    post_times.append(area_list.count(index))
print(post_times)

def data_gen(types):
    length = 0
    if length <= len(area_index):
        for area, times in zip(area_index,post_times):
            data = {
                'name': area,
                'data': [times],
                'type': types
            }
            yield data
            length += 1

# data_gen('column')

for i in data_gen('column'):
    # print(i)
    pass

series3 = [data for data in data_gen('column')]  # 比for循环好
charts.plot(series3, show='inline', options=dict(title=dict(text='二手物品发帖数')))

二、N日内制定地区的发帖量的变化曲线

1、整理清晰数据

2、更新数据库

3、数据的可视化

db.collection.find()

find(?,?)

?文件是谁,?看什么数据

{id:1,name:0,info:3,cate:4}

find({id:1},{name:1,info:1}) 这里的1是true,0是false,查看这两个字段

所以上面是可以看到的

# for i in item_info.find({},{'area':1,'_id':0}).limit(100):
#    print(i) # 只展cc示id和area
# for i in item_info.find({'date': '2019-12-05'}, {'area': {'$slice': 1}, 'title': 0, 'price': 0, '_id': 0}).limit(100):
# 没有指定显示,就有可能全部显示,只能指定详细参数的化,其他必须手工指定0
for i in item_info.find({'date': {'$in': ['2018-02-05', '2020-02-01']}}, {'area': {'$slice': 1}, 'title': 0, 'price': 0, '_id': 0}).limit(100):
    print(i) # 只展cc示id和area
# 已知 日期 区域名称 朝阳海淀
# 单日地区发帖量

1、让程序明白时间段,获得单日日期

2、使用find函数查找指定数据

3、转化数据

# 已知 日期 区域名称 朝阳海淀
# 单日地区发帖量
for i in item_info.find({},{'_id': 0, 'date': 1}).limit(100):
    print(i)

#分割- 成.
for i in item_info.find():
    frags = i['date'].split('-')
    if len(frags) == 1:
        date = frags[0]
    else:
        date = '{}.{}.{}'.format(frags[0],frags[1],frags[2])
        print(date)
# item_info.update_one({'_id':i['_id']},{'$set':{'date':date}})

 让程序指导发帖时间范围

# 转换时间 date
a = date(2015,5,10)
print(a)
b = timedelta(days= 1)
print(b)
#1 day, 0:00:00

def get_all_dates(date1,date2):
    the_date = date(int(date1.split('-')[0]),int(date1.split('-')[1]),int(date1.split('-')[2]))
    end_date = date(int(date2.split('-')[0]),int(date2.split('-')[1]),int(date2.split('-')[2]))
    days = timedelta(days = 1)
    while the_date <= end_date:
        yield the_date.strftime('%Y.%m.%d')
        the_date = the_date + days

for i in get_all_dates('2019-12-01','2020-02-01'):
    print(i)

根据已知,求解未知信息

#求解
def get_data_within(date1,date2,areas):
    for area in areas:
        for date in get_all_dates(date1,date2):
            # 一个区域多少条
            a = list(item_info.find({'date': date, 'area': area}))
            print('#'*20,date,area,len(a),'#'*20)
            #len(a)

get_data_within('2019-11-01','2020-02-01',['朝阳'])

格式数据

# 调整数据格式
#求解
def get_data_within2(date1,date2,areas):
    for area3 in areas:
        area_day_posts = []
        for date in get_all_dates(date1,date2):
            # 一个区域多少条
            a = list(item_info.find({'date': date, 'area': area3}))
            each_day_post = len(a)
            area_day_posts.append(each_day_post)
        data3 = {
            'name':area3,
            'data':area_day_posts,
            'type':'line'
        }
        yield  data3

for i in get_data_within2('2019-11-01','2020-02-01',['朝阳','海淀','通州']):
    print(i)
options2 = {
    'charts' : {'zoomType':'xy'},
    'title' : {'text':'发帖量统计'},
    'subtitle': {'text': '可视化统计图表'},
    'xAxis' : {'categories': [i for i in get_all_dates('2020-01-01','2020-02-01')]},
    'yAxis' : {'title':{'text':'数量'}}
}
series4 = [i for i in get_data_within2('2019-11-01','2020-02-01',['朝阳','海淀','通州'])]
charts.plot(series4, show='inline', options=options2)

某一天二手物品在随后七天内交易时长为1天的类目分布占比

collection.aggregate(pipeline)

databas == pipeline ==data 管道叠加

pipeline = [{$match:?},{$group:?},{$sort:?},{$limit:?},

{$skip:?},{$unwind:?},{$redact:?},{$sample:?},{$out:?}]

一共有13中,常用的是前面的四种

#某一天二手货物品咋随后7天内,交易市场为1天的类目分布占比
for i in item_info.find().limit(100):
    #print(i)
    pass
# time 0 表示7天每卖出去,为其他的表示几天卖出去
pipline = [
    # {'$match':{'date':'2019-12-05'}}
    {'$match': {'$or': [{'date': '2019-12-05'}, {'date': '2020-02-01'}]}},
    {'$group': {'_id': '$price', 'counts': {'$sum': 1}}},
    #接受两个参数 _id(从price进行二次复用为id) 第二个某项进行求和 1是表示+1
    {'$sort': {'counts': 1}},
    # 1正 -1倒叙
    {'$limit': 100}
]
for i in item_info.aggregate(pipline):
    #print(i)
    pass
pipline2 = [
    {'$match': {'$or': [{'date': '2019-12-05'}, {'date': '2020-02-01'}]}},
    {'$group': {'_id': {'$slice':['$area',1,1]}, 'counts': {'$sum': 1}}},
    #slice  可以对list直接进行分割,然后第一个1,跳过第一个,第二个1,取第1个
    {'$sort': {'counts': -1}},
]
for i in item_info.aggregate(pipline2):
    #print(i)
    pass
def data_gen(date4,date5):
    pipline3 = [
        {'$match': {'$or': [{'date': date4}, {'date': date5}]}},
        {'$group': {'_id': {'$slice': ['$area', 0, 1]}, 'counts': {'$sum': 1}}},
        # slice  可以对list直接进行分割,然后第一个1,跳过第一个,第二个1,取第1个
        {'$sort': {'counts': -1}},
    ]
    for i in item_info.aggregate(pipline3):
        #yield[i['_id'][0],i['counts']] 0表示把list第一个值拿出来
        yield [i['_id'][0], i['counts']]
for i in data_gen( '2019-12-05','2020-02-01'):
    #print(i)
    pass
options3 = {
    'charts' : {'zoomType':'xy'},
    'title' : {'text':'发帖量统计'},
    'subtitle': {'text': '可视化统计图表'}
}
series5 = {
    'type':'pie',
    'name':'饼图',
    'data':[i for i in data_gen( '2019-12-05','2020-02-01')]
}
charts.plot(series5, show='inline', options=options2)

完成~~~~

#某段时间内背景某个城区发帖量的top3类目
#某个时间段
#某个地区
#series6 = [{'name':'name','data':[100],'type':'column'},{'name':'name','data':[100],'type':'column'}]
#实际上{name 类目.data 发帖量}
#目标{'_id':['北京二手'],'counts':175}
pipeline4 = [
    {'$match': {'$and':[{'date': {'$gte':'2019-12-01','$lte':'2020-02-02'}},{'area':{'$all':['朝阳']}}]}},
    #{'$group': {'_id': {'$slice': ['$cates',0,1]},'counts':{'$sum': 1}}},
    {'$group': {'_id': '$price','counts':{'$sum': 1}}},
    {'$limit': 3}
]
for i in item_info.aggregate(pipeline4):
    #print(i)
    pass
#某段时间内各大类目中成色对应的平均价格
def data_gen2(date1,date2,area,limit):
    pipeline4 = [
        {'$match': {'$and': [{'date': {'$gte': date1, '$lte': date2}}, {'area': {'$all': area}}]}},
        # {'$group': {'_id': {'$slice': ['$cates',0,1]},'counts':{'$sum': 1}}},
        {'$group': {'_id': '$price', 'counts': {'$sum': 1}}},
        {'$limit': limit}
    ]
    for i in item_info.aggregate(pipeline4):
        data = {
            'name':i['_id'][0],
            'data': [i['counts']],
            'type':'column'
        }
        yield data
for i in data_gen2('2019-10-01','2020-02-02',['朝阳'],3):
    # print(i)
    pass
series6 = [ i for i in data_gen2('2019-10-01','2020-02-02',['朝阳'],3)]
options4 = {
    'charts' : {'zoomType':'xy'},
    'title' : {'text':'发帖量统计'},
    'subtitle': {'text': '可视化统计图表'}
}
charts.plot(series6,options=options4,show='inline')
#某段时间内各大类目中成色对应的平均价格
#某个时间段,
#各大类目或者地区
#单个产品价格

#series=['data1','data2','data3',]
#实际上[全新价格,9成新价格]
#目标{'avg_price':300,'_id':7成新以下}

# jsbeautifier.org 进行格式化
pipline4 = [
    {'$match':{'$and':[{'date':{'$gte':'2019-01-01','$lte':'2020-02-02'}},
               {'area':{'$all':['朝阳']}},
                {'person':{'$nin':['-']}}
     ]}},
    {'$group':{'_id':'$date','avg_price':{'$max':'$price'}}},
    {'$sort':{'avg_price':-1}}
]
for i in item_info.aggregate(pipline4):
    print(i)

def data_gen3(date1,date2,area):
    pipline4 = [
        {'$match': {'$and': [{'date': {'$gte': date1, '$lte': date2}},
                             {'area': {'$all': area}},
                             {'person': {'$nin': ['-']}}
                             ]}},
        {'$group': {'_id': '$date', 'avg_price': {'$max': '$price'}}},
        {'$sort': {'avg_price': -1}}
    ]
    for i in item_info.aggregate(pipline4):
        yield i['avg_price']
data = [i for i in data_gen3('2019-01-01','2020-02-02',['朝阳'])]
options5 = {
    'title' : {'text':'发帖量统计'},
    'xAxis': {'categories': ['2019-11-11','2019-11-24']},
    'yAxis': {'title': {'text':'价格'}},
}
charts.plot(data,show='inline',options=options5)
#mongoexport -d ceshi - c item_info -o  cc.csv

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值