前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >pandas每天一题-探索分析:推测点餐人数

pandas每天一题-探索分析:推测点餐人数

作者头像
咋咋
发布2021-09-01 12:18:43
3500
发布2021-09-01 12:18:43
举报
文章被收录于专栏:数据大宇宙

前面我们一直在讲解 pandas 数据处理的各种知识点,现在开始就应用上这些知识点来探索一下点餐数据。

本系列计划每天更新一期,希望各位小伙伴先自行思考,再查看答案。如果对你有帮助,记得转发推荐给你的好友!

上期文章:pandas每天一题-探索分析:找出最受欢迎的二次点餐菜式

后台回复"数据",可以下载本题数据集

如下数据:

代码语言:javascript
复制
import pandas as pd
import numpy as np
from itertools import combinations

df = pd.read_csv('chipotle.tsv',
                 sep='\t',
                 converters={'item_price': lambda x: float(x[1:-1])})

df

数据描述:

  • 此数据是订单明细表。一个订单会包含很多明细项,表中每个样本(每一行)表示一个明细项
  • order_id 列存在重复
  • item_name 是品类名称,例如"罐装饮料"
  • quantity 是明细项数量
  • item_price 是该明细项的总价钱
  • choice_description 是每一项更详尽的描述,例如:"雪碧"

例如, 某个单子中,客人点餐

  • 牛排玉米饼
  • 烧烤玉米饼
  • 1罐可乐
  • 1罐雪碧

于是产生了4行记录:

前面章节讲解过的知识点,本文不再讲解!

需求:

店铺需要重新装修,此时你希望知道点餐人数的情况。可惜点餐系统没有记录人数。

请使用以上数据,对点餐人数做合理推测

下面是答案了


假设

这个需求挺有意思,解决思路也很多。这一节我们从饮料入手,推测点餐人数。

首先,尽可能找出品类是饮料的记录看看:

代码语言:javascript
复制
cond = df['item_name'].str.contains('drink|soda|bottled|water',case=False)
df[cond].drop_duplicates(['item_name','choice_description'])
  • 行1:drink|soda|bottled|water 这是正则表达式,找出包含这些单词的记录

问:为什么是这4个单词?

答:我人工看的

问:。。。。。。。

总的来说,品类只有4种:

代码语言:javascript
复制
items = ['Canned Soda','Canned Soft Drink','6 Pack Soft Drink','Bottled Water']
df.query('item_name in @items')
  • 这就得到所有饮料的记录

6 Pack Soft Drink 是6瓶装的饮料,比起单点6瓶 Canned Soft Drink 更优惠

那么,如果你是一个人来吃饭,不可能点6瓶装吧。

这就是一个大概率的推测。这些订单大概率是多人就餐(估计至少是4至6人):

代码语言:javascript
复制
(
    df.query('item_name == "6 Pack Soft Drink"')['order_id']
    .drop_duplicates()
)

得到的就是至少4-6人的订单

其中,还有叫了1打可乐的订单:

代码语言:javascript
复制
df.query('item_name == "6 Pack Soft Drink" and and quantity>1')
  • 这桌至少10-12人吧

细致一些

有没有人是点了6瓶装,然后再单点了单瓶的饮料?

代码语言:javascript
复制
items = ['Canned Soda','Canned Soft Drink','Bottled Water']

def each(xdf):
    has_6d= (xdf['item_name']=='6 Pack Soft Drink').any()
    has_others = (xdf['item_name'].isin(items)).any()
    return has_6d and has_others

df.groupby('order_id').filter(each)
  • 行8:对订单分组筛选
  • 行4:是否点了6瓶装,这里注意,括号中的判断返回的是 bool列(Series),我们需要的是一个 bool 值,所以用any确定里面是否至少有一个 True
  • 行5:同理,判断是否含有其他的饮料,这里用 isin 可以判断多个值
  • 行6:2个条件同时成立,就是我们需要的订单记录组

注意看数据,这桌应该是有15个人,点了6瓶可乐+9瓶水。

为什么不是7个人吃饭,走的时候再点水拿走?

因为他们还点了15人份的沙拉


单点入手

接下来我们找一些单瓶装的饮料,但是数量是多于1的。这些也是有可能多人就餐:

代码语言:javascript
复制
items = ['Canned Soda','Canned Soft Drink','Bottled Water']
(
    df.query("item_name in @items and quantity>1")
    .drop_duplicates(['order_id'])
    .sort_values('quantity',ascending=False)
)
  • 这很好理解

但是也有一种情况,多人就餐,不同的人点了不同的饮料。此时订单中就会出现多笔饮料的记录,数量是1。

从数据角度来说,就是找出同一个订单中,出现3种饮料品类之一,并且他们的数量(quantity)是1,并且记录数多于1条的订单:

代码语言:javascript
复制
items = ['Canned Soda','Canned Soft Drink','Bottled Water']

def each(xdf):
    return len(xdf)>1

(
    df.query("item_name in @items and quantity==1")
    .groupby('order_id').filter(each)
    .sort_values(['order_id','item_name'])
)
  • 行7:整体把无关的 品类过滤掉
  • 行8:每组订单筛选
  • 行4:筛选条件很简单,记录多于1条

不过这里的结果也可能是一个人就餐,点了2次饮料。

重复点餐的分析请看上一节

由此,我们把多于2笔的取出来,这些订单更有可能是多人就餐,人数就是饮料数量。

修改一下之前的filter逻辑即可:

代码语言:javascript
复制
items = ['Canned Soda','Canned Soft Drink','Bottled Water']

def each(xdf):
    return len(xdf)>2

(
    df.query("item_name in @items and quantity==1")
    .groupby('order_id').filter(each)
    .sort_values(['order_id','item_name'])
)
  • 行4:修改为大于2

更多有趣的探索,下一节继续,记得点赞三连!!!!


推荐阅读:

  1. Python做人工智能?让电脑自己学会玩游戏,实战带你入门机器学习中的强化学习
  2. 懂Excel轻松入门Python数据分析包pandas(十八):pandas 中的 vlookup
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-06-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据大宇宙 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 假设
  • 细致一些
  • 单点入手
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档