第三周/第四节课程: 使用聚合管道高效查找数据

2016-07-29  本文已影响30人  uvscjh

1. 引言

统计某日发布的二手物品在随后七天内, 交易完成时间是一天的类目分布占比.
也就是有哪些类目当天发布当天就有人买了.

2. 分析

database -> pipeline -> data
不同管道有不同的作用, 有的负责筛选匹配, 有的负责聚合整合统计, 还有的负责重新分组重新命名, 之后各管道叠加起来


Paste_Image.png

3. 实现

In [1] :
from pymongo import MongoClient
from string import punctuation
from datetime import timedelta, date
import charts

In [2] :
client = MongoClient('10.66.17.17', 27017)
database = client['ganji']
item_info = database['item_info']

In [3] :
# 查看下源数据
[i for i in item_info.find().limit(3)]
Out [3] :
[{'_id': ObjectId('5698f524a98063dbe9e91ca8'),
  'area': ['朝阳', '高碑店'],
  'cates': ['北京58同城', '北京二手市场', '北京二手家电', '北京二手冰柜'],
  'look': '-',
  'price': 450,
  'pub_date': '2016.01.12',
  'time': 0,
  'title': '【图】95成新小冰柜转让 - 朝阳高碑店二手家电 - 北京58同城',
  'url': 'http://bj.58.com/jiadian/24541664530488x.shtml'},
 {'_id': ObjectId('5698f525a98063dbe4e91ca8'),
  'area': ['朝阳', '定福庄'],
  'cates': ['北京58同城', '北京二手市场', '北京二手家电', '北京二手洗衣机'],
  'look': '-',
  'price': 1500,
  'pub_date': '2016.01.14',
  'time': 2,
  'title': '【图】洗衣机,小冰箱,小冰柜,冷饮机 - 朝阳定福庄二手家电 - 北京58同城',
  'url': 'http://bj.58.com/jiadian/24349380911041x.shtml'},
 {'_id': ObjectId('5698f525a98063dbe7e91ca8'),
  'area': ['朝阳', '望京'],
  'cates': ['北京58同城', '北京二手市场', '北京二手台式机/配件'],
  'look': '-',
  'price': 1500,
  'pub_date': '2015.12.27',
  'time': 3,
  'title': '【图】三星 A5 白色 没有打开过 - 朝阳望京台式机/配件 - 北京58同城',
  'url': 'http://bj.58.com/diannao/24475337853109x.shtml'}]

In [4] :
# 定义pipeline模型
pipeline = [
    # 大于某个日期小于某个日期且3天内完成成交的
    # {'$match': {'$and': [{'pub_date': {'$gt': '2015.12.24', '$lt': '2015.12.26'}}, {'time': 3}]}},
    # 发布日期为'2015.12.24'且3天内完成成交的
    {'$match': {'$and': [{'pub_date': '2015.12.24'}, {'time': 3}]}},
    # 以源数据的'price'字段分组, 且统计其出现次数, 出现一次则加1, '$sum'后的数字是多少就加多少
    {'$group': {'_id': '$price', 'counts': {'$sum': 1}}},
    # 排序, 指定以什么字段排序, 1为从低到高, -1为从高到低
    {'$sort': {'counts': -1}},
    # 限制显示多少条数据
    {'$limit': 10},
]

In [5] :
[i for i in item_info.aggregate(pipeline)]
Out [5] :
[{'_id': 0, 'counts': 14},
 {'_id': 1000, 'counts': 11},
 {'_id': 300, 'counts': 7},
 {'_id': 100, 'counts': 6},
 {'_id': 50, 'counts': 5},
 {'_id': 1800, 'counts': 5},
 {'_id': 700, 'counts': 4},
 {'_id': 200, 'counts': 4},
 {'_id': 350, 'counts': 4},
 {'_id': 3000, 'counts': 3}]

In [6] :
# 定义pipeline模型
pipeline2 = [
    {'$match': {'$and': [{'pub_date': '2015.12.28'}, {'time': 1}]}},
    {'$group': {'_id': {'$slice': ['$cates', 2, 1]}, 'counts': {'$sum': 1}}},
    {'$sort': {'counts': -1}},
]

In [7] :
# 打印看下管道模型的输出结果
[i for i in item_info.aggregate(pipeline2)]
Out [7] :
[{'_id': ['北京二手家电'], 'counts': 40},
 {'_id': ['北京二手服装/鞋帽/箱包'], 'counts': 21},
 {'_id': ['北京二手母婴/儿童用品'], 'counts': 18},
 {'_id': ['北京二手图书/音像/软件'], 'counts': 17},
 {'_id': ['北京二手台式机/配件'], 'counts': 15},
 {'_id': ['北京二手办公用品/设备'], 'counts': 14},
 {'_id': ['北京二手文体/户外/乐器'], 'counts': 12},
 {'_id': ['北京二手数码产品'], 'counts': 10},
 {'_id': ['北京二手手机'], 'counts': 8},
 {'_id': ['北京二手笔记本'], 'counts': 6},
 {'_id': ['北京其他二手物品'], 'counts': 6},
 {'_id': ['北京二手平板电脑'], 'counts': 5}]

In [8] :
# 定义函数方便快速生成图表数据
def time_data_gen(date, time):
    # 定义管道模型
    pipeline = [
        {'$match': {'$and': [{'pub_date': date}, {'time': time}]}},
        {'$group': {'_id': {'$slice': ['$cates', 2, 1]}, 'counts': {'$sum': 1}}},
        {'$sort': {'counts': -1}},
    ]
    # 生成所有数据
    for i in item_info.aggregate(pipeline):
        yield [i['_id'][0], i['counts']]
# 输出看下结果        
[i for i in time_data_gen('2015.12.28', 1)]
Out [8] :
[['北京二手家电', 40],
 ['北京二手服装/鞋帽/箱包', 21],
 ['北京二手母婴/儿童用品', 18],
 ['北京二手图书/音像/软件', 17],
 ['北京二手台式机/配件', 15],
 ['北京二手办公用品/设备', 14],
 ['北京二手文体/户外/乐器', 12],
 ['北京二手数码产品', 10],
 ['北京二手手机', 8],
 ['北京二手笔记本', 6],
 ['北京其他二手物品', 6],
 ['北京二手平板电脑', 5]]

In [9] :
# 图表参数
options = {
    'char': {'zoomType': 'xy'},
    'title': {'text': '发帖量统计, 好看又好玩'},
    'subtitle': {'text': '某日发布的二手物品在随后七天内, 交易完成时间是一天的类目分布占比'},
}

In [10] :
# 图表数据
serises = {
    'type': 'pie',
    'data': [i for i in time_data_gen('2015.12.28', 1)],
    'name': 'One day',
}
# 输出饼状图表
charts.plot(serises, show='inline', options=options)
Out [10] :
Paste_Image.png

4. 总结

上一篇 下一篇

猜你喜欢

热点阅读