分组名称简单
这是一个关于 pandas 从基础到进阶的练习题系列,来源于 github 上的 guipsamora/pandas_exercises 。这个项目从基础到进阶,可以检验你有多么了解 pandas。
我会挑选一些题目,并且提供比原题库更多的解决方法以及更详尽的解析。
计划每天更新一期,希望各位小伙伴先自行思考,再查看答案。如果对你有帮助,记得转发推荐给你的好友!
上期文章:pandas每天一题-题目17:缺失值处理的多种方式
后台回复”数据”,可以下载本题数据集
如下数据:
1import pandas as pd
2import numpy as np
3
4df = pd.read_csv(‘chipotle.tsv’,
5 sep=’t’,
6 converters={‘item_price’: lambda x: float(x[1:-1])})
数据描述:
此数据是订单明细表。一个订单会包含很多明细项,表中每个样本(每一行)表示一个明细项
order_id 列存在重复
item_name 是明细项物品名称
quantity 是明细项数量
item_price 是该明细项的总价钱
choice_description 是每一项更详尽的描述
例如:某个单子中,客人要 1瓶可乐 和 1瓶雪碧 ,那么这个订单的 order_id 为:’xx’,有2个行记录(样本),2行的item_name 都是 “Canned Soda”(苏打水,视为罐装饮料) ,quantity 都是1。
第一行的 choice_description 是 “Diet Coke”(可乐) ,第二行是 “Sprite”(雪碧)
前面章节讲解过的知识点,本文不再讲解!
需求:
找到 choice_description 的缺失值,并使用同样的 item_name 的值进行填充
同上,如果 同组item_name 中出现多个不同的 choice_description ,使用出现频率最高的进行填充
同上,如果存在多个 choice_description 的出现频率一致,随机选取填充
下面是答案了
构建数据原题数据的缺失值情况比较简单,为此我改造一下数据。
定义一个函数,方便修改数据:
1def modify(*idx):
2 ret = df.query(“item_name in [‘Salad’,’Izze’]”).copy()
3 ret.loc[idx,’choice_description’]=np.nan
4 return ret
5
6modify(430,1414)
为了方便查看效果,我们只看2个品类 [‘Salad’,’Izze’]
现在我们希望使用同组 item_name 对应的值填充其缺失值。
1dfx = modify(430, 1414)
2dfx[‘choice_description’] =(
3 dfx.groupby(‘item_name’)[‘choice_description’]
4 .fillna(method=’ffill’)
5)
6
7dfx
行3:按 item_name 分组,然后取出每一组的 choice_description 列
行4:此时我们可以直接指定各种列(Series)的操作。fillna 是上一节介绍过的前向填充
从结果上看到,行索引 1414 是 Salad 组内第一条记录。所以他无法找到上一笔记录参考填充
有没有办法把 Salad 的缺失值填上?
1dfx = modify(430, 1414)
2
3dfx[‘choice_description’] =(
4 dfx.sort_values([‘item_name’,’choice_description’])
5 .groupby(‘item_name’)[‘choice_description’]
6 .fillna(method=’ffill’)
7)
8
9dfx
行4:道理很简单,把 nan 的记录尽量往下放。sort_values 有参数 na_position 控制 nan 的位置,默认情况下是 ‘last’,放置在最后
按频率填充看看 lzze 这个品类的细分描述有多少:
1dfx = modify(1, 1414)
2
3(
4 dfx.groupby(‘item_name’)[‘choice_description’]
5 .value_counts()
6 .to_frame()
7)
注意我们这次把行索引1的记录修改为nan
这里可以发现,其实大部分的表(DataFrame)或列(Series)的操作都能用于分组操作
现在希望使用组内出现频率最高的值来填充组内的缺失值:
1dfx = modify(1, 1414)
2
3def each_gp(x):
4 v = x.value_counts().index[0]
5 return x.fillna(v)
6
7dfx[‘choice_description’] =(
8 dfx.groupby(‘item_name’)[‘choice_description’]
9 .apply(each_gp)
10)
11
12dfx
行9:pandas 正在灵活之处在于在分组时能够用自定义函数指定每个组的处理逻辑
行3-5:此时数据有2组(2个不同的 item_name值),因此这个自定义函数被执行2次,参数x就是每一组的 choice_description 列(Series)
行4:使用 value_counts 统计每个值的频数,然后取出第一笔的索引值(choice_description 的值)
推荐阅读:
入门Python,这些JupyterNotebook技巧就是你必须学的
懂Excel轻松入门Python数据分析包pandas(二十八):二分法查找