前面我们一直在讲解 pandas 数据处理的各种知识点,现在开始就应用上这些知识点来探索一下点餐数据。
本系列计划每天更新一期,希望各位小伙伴先自行思考,再查看答案。如果对你有帮助,记得转发推荐给你的好友!
上期文章:pandas每天一题-探索分析:找出最受欢迎的二次点餐菜式
后台回复"数据",可以下载本题数据集
如下数据:
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
数据描述:
例如, 某个单子中,客人点餐
于是产生了4行记录:
前面章节讲解过的知识点,本文不再讲解!
需求:
店铺需要重新装修,此时你希望知道点餐人数的情况。可惜点餐系统没有记录人数。
请使用以上数据,对点餐人数做合理推测
下面是答案了
这个需求挺有意思,解决思路也很多。这一节我们从饮料入手,推测点餐人数。
首先,尽可能找出品类是饮料的记录看看:
cond = df['item_name'].str.contains('drink|soda|bottled|water',case=False)
df[cond].drop_duplicates(['item_name','choice_description'])
drink|soda|bottled|water
这是正则表达式,找出包含这些单词的记录问:为什么是这4个单词?
答:我人工看的
问:。。。。。。。
总的来说,品类只有4种:
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人):
(
df.query('item_name == "6 Pack Soft Drink"')['order_id']
.drop_duplicates()
)
得到的就是至少4-6人的订单
其中,还有叫了1打可乐的订单:
df.query('item_name == "6 Pack Soft Drink" and and quantity>1')
有没有人是点了6瓶装,然后再单点了单瓶的饮料?
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)
注意看数据,这桌应该是有15个人,点了6瓶可乐+9瓶水。
为什么不是7个人吃饭,走的时候再点水拿走?
因为他们还点了15人份的沙拉
接下来我们找一些单瓶装的饮料,但是数量是多于1的。这些也是有可能多人就餐:
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条的订单:
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'])
)
不过这里的结果也可能是一个人就餐,点了2次饮料。
重复点餐的分析请看上一节
由此,我们把多于2笔的取出来,这些订单更有可能是多人就餐,人数就是饮料数量。
修改一下之前的filter逻辑即可:
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'])
)
更多有趣的探索,下一节继续,记得点赞三连!!!!
推荐阅读: