前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >pandas每天一题-题目18:分组填充缺失值

pandas每天一题-题目18:分组填充缺失值

作者头像
咋咋
发布2021-09-01 14:15:47
2.9K0
发布2021-09-01 14:15:47
举报
文章被收录于专栏:数据大宇宙

这是一个关于 pandas 从基础到进阶的练习题系列,来源于 github 上的 guipsamora/pandas_exercises 。这个项目从基础到进阶,可以检验你有多么了解 pandas。

我会挑选一些题目,并且提供比原题库更多的解决方法以及更详尽的解析

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

上期文章:pandas每天一题-题目17:缺失值处理的多种方式

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

如下数据:

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

df = pd.read_csv('chipotle.tsv',
                 sep='\t',
                 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"(雪碧)

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

需求:

  1. 找到 choice_description 的缺失值,并使用同样的 item_name 的值进行填充
  2. 同上,如果 同组item_name 中出现多个不同的 choice_description ,使用出现频率最高的进行填充
  3. 同上,如果存在多个 choice_description 的出现频率一致,随机选取填充

下面是答案了


构建数据

原题数据的缺失值情况比较简单,为此我改造一下数据。

定义一个函数,方便修改数据:

代码语言:javascript
复制
def modify(*idx):
    ret = df.query("item_name in ['Salad','Izze']").copy()
    ret.loc[idx,'choice_description']=np.nan
    return ret

modify(430,1414)

为了方便查看效果,我们只看2个品类 ['Salad','Izze']

现在我们希望使用同组 item_name 对应的值填充其缺失值。

代码语言:javascript
复制
dfx = modify(430, 1414)
dfx['choice_description'] =(
    dfx.groupby('item_name')['choice_description']
        .fillna(method='ffill')
)

dfx
  • 行3:按 item_name 分组,然后取出每一组的 choice_description
  • 行4:此时我们可以直接指定各种列(Series)的操作。fillna 是上一节介绍过的前向填充
  • 从结果上看到,行索引 1414 是 Salad 组内第一条记录。所以他无法找到上一笔记录参考填充

有没有办法把 Salad 的缺失值填上?

代码语言:javascript
复制
dfx = modify(430, 1414)

dfx['choice_description'] =(
    dfx.sort_values(['item_name','choice_description'])
        .groupby('item_name')['choice_description']
        .fillna(method='ffill')
)

dfx
  • 行4:道理很简单,把 nan 的记录尽量往下放。sort_values 有参数 na_position 控制 nan 的位置,默认情况下是 'last',放置在最后

按频率填充

看看 lzze 这个品类的细分描述有多少:

代码语言:javascript
复制
dfx = modify(1, 1414)

(
    dfx.groupby('item_name')['choice_description']
        .value_counts()
        .to_frame()
)
  • 注意我们这次把行索引1的记录修改为nan

这里可以发现,其实大部分的表(DataFrame)或列(Series)的操作都能用于分组操作

现在希望使用组内出现频率最高的值来填充组内的缺失值:

代码语言:javascript
复制
dfx = modify(1, 1414)

def each_gp(x):
    v = x.value_counts().index[0]
    return x.fillna(v)

dfx['choice_description'] =(
    dfx.groupby('item_name')['choice_description']
        .apply(each_gp)
)

dfx
  • 行9:pandas 正在灵活之处在于在分组时能够用自定义函数指定每个组的处理逻辑
  • 行3-5:此时数据有2组(2个不同的 item_name值),因此这个自定义函数被执行2次,参数x就是每一组的 choice_description 列(Series)
  • 行4:使用 value_counts 统计每个值的频数,然后取出第一笔的索引值(choice_description 的值)

推荐阅读:

  1. 入门Python,这些JupyterNotebook技巧就是你必须学的
  2. 懂Excel轻松入门Python数据分析包pandas(二十八):二分法查找
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-06-16,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 构建数据
  • 按频率填充
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档