对DataFrame进行过滤
文章目录
该文章内容为《Pandas数据分析实战》的学习笔记
导入本文需要的包以及数据
import pandas as pd
pd.read_csv("./pandas-in-action-master/chapter_05_filtering_a_dataframe/employees.csv")
# 使用`parse_dates`参数将Start Date列的文本值转换为日期时间类型,这样可以允许我们对日期进行更多的操作
employees = pd.read_csv("./pandas-in-action-master/chapter_05_filtering_a_dataframe/employees.csv",
parse_dates = ["Start Date"])
优化数据集以提高内存使用效率
info
方法可以查看列的列表,数据类型、缺失值的数量,以及DataFrame的总内存消耗
employees.info()
使用astype方法转换数据类型
Pandas将Mgmt列的值作为字符串导入,我们可以将其转换为更加轻量级的布尔类型来减少内存使用
employees["Mgmt"] = employees["Mgmt"].astype(bool)
但注意,这样会将NaN转换为为True
我们还可以将Salary列的浮点数转换为整数。但此时用astype转换会因为存在缺失值报错。我们可以先用fillna
方法进行对NaN进行填充再转换
employees["Salary"] = employees["Salary"].fillna(0).astype(int)
Pandas包含一种称为category的特殊数据类型,非常适合那些由若干唯一值组成的列
employees.nunique()
从上面代码的输出结果可以看出Gender和Team分别只有2和10个唯一值,非常合适
employees["Gender"] = employees["Gender"].astype("category")
employees["Team"] = employees["Team"].astype("category")
这时候可以通过info
看到使用内存显著下降
employees.info()
按单个条件过滤
生成员工Maria的列表,这里我们要用到相等运算符(==)
employees["First Name"] == "Maria"
这里会返回一个布尔类型的Series,这个就是接下来用来索引的关键
employees[employees["First Name"] == "Maria"]
同样的我们还可以筛选不在Finance团队的员工记录
temp = employees["Team"] != "Finance"
employees[temp]
要注意这里Pandas认为NaN不等于Finance
检索公司中的所有经理,因为Mgmt列已经是布尔类型,所以更加简单
employees[employees["Mgmt"]]
还可以使用算数运算符来过滤,比如下面就是过滤薪水超过100000的员工
high_earners = employees["Salary"] > 100000
employees[high_earners]
按多个条件过滤
AND条件
查找Business Dev团队工作的女性员工
is_female = employees["Gender"] == "Female"
is_biz_dev = employees["Team"] == "Business Dev"
employees[is_biz_dev & is_female]
再找出其中的经理
is_menger = employees["Mgmt"]
employees[is_menger & is_female & is_biz_dev]
OR条件
找到所有薪水低于40000并且入职日期在2015年1月1日之后的员工
earning_below_40000 = employees["Salary"] < 40000
started_after_2015 = employees["Start Date"] > "2015-01-01"
employees[earning_below_40000 | started_after_2015]
~条件
~
反转布尔Series中的值
比如找出薪水大于等于40000的员工,我们还可以这样
employees[~earning_below_40000]
按条件过滤
isin
方法
上面我们提到了如果想要找到一个团队的员工可以用这种方法:employess[employees["Team"] != "Finance"]
如果要找多个团队,可以用|
,但如果要找的数量很大,这样一个个打就十分低效。我们可以用下面这种方法
all_star_teams = ["Sales", "Legal", "Marketing"]
on_all_star_teams = employees["Team"].isin(all_star_teams)
employees[on_all_star_teams]
between
方法
在处理时间和日期的时候,通常希望提取特定范围内的值。这里就可以用到between
between_80k_and_90k = employees["Salary"].between(80000, 90000)
employees[between_80k_and_90k]
eighties_folk = employees["Start Date"].between(
left = "1980-01-01",
right = "1990-01-01"
)
employees[eighties_folk]
isnull
和notnull
方法
isnull
方法返回一个布尔Series,其中True表示该位置为空值
employees["Team"].isnull()
notnull
方法返回一个与
isnull`相反的Series
利用这些布尔Series可以提取特定的DataFrame行。比如,提取所有缺少Team数据的员工
no_team = employees["Team"].isnull()
employees[no_team]
处理空值
将数据集恢复到原始状态
employees = pd.read_csv("./pandas-in-action-master/chapter_05_filtering_a_dataframe/employees.csv",
parse_dates = ["Start Date"])
使用dropna
方法删除包含任何NaN值的行。
employees.dropna()
将how参数设置为all可以删除所有列都为空的行
employees.dropna(how = "all")
subset参数可以用来获得特定列中带有缺失值的行。例如,删除Gender列中带有缺失值的行
employees.dropna(subset = ["Gender"])
employees.dropna(subset = ["Gender", "Salary"])
thresh参数指定行必须含有的非空值的最小阈值,Pandas才能保留他。
employees.dropna(thresh = 4)
处理重复值
duplicated
方法
duplicated
方法返回一个布尔型Series,用于识别列中的重复项,只要有之前在Series中遇到的值,它就会返回True
employees["Team"].head()
employees["Team"].duplicated()
其中的keep参数设置为first代表保留重复值第一次出现的值。last代表保留最后一次出现的值
通过这个方法我们可以实现从每个团队提取一名员工
employees[~employees["Team"].duplicated()]
drop_duplicates
方法
该方法在默认情况下,如果有多个列,所有列的值都相同,将保留第一行,并将其他行删除
通过设置subset参数可以设置该方法只看哪些行
employees.drop_duplicates(subset = "Team")
该方法也有与
duplicated
方法相似的keep参数,处理duplicated
方法keep参数的用法,其还可以传入False来排出所有包含重复值的行
代码挑战
netflix.csv
数据集是 2019 年 11 月可在视频流媒体服务 Netflix 上观看的近 6000 个标题的集合。
该数据集包含 4 列数据:
- 视频的标题
- 导演
- Netflix 添加它的日期(
date_added
) - 视频的类型(如 Movie)
其中 director
和 date_added
列包含缺失值。
使用在本章中学到的知识,完成以下挑战:
- 为发挥最大效用,对数据集的内存使用进行优化。
- 查找标题为 “Limitless” 的所有行。
- 查找由 “Robert Rodriguez” 导演的
Movie
类型的所有行。 - 查找
date_added
列为 “2019-07-31” 或 导演为 “Robert Altman” 的所有行。 - 查找导演为 “Orson Welles” “Aditya Kripalani” 或 “Sam Raimi” 的所有行。
- 查找
date_added
值在 2019 年 5 月 1 日到 2019 年 6 月 1 日范围内的所有行。 - 删除
director
列中所有包含 NaN 值的行。 - 确定 Netflix 仅添加一部电影到其目录中的日期。
# 1
netflix.nunique()
netflix["type"] = netflix["type"].astype("category")
# 2
netflix[netflix["title"] == "Limitless"]
# 3
netflix[(netflix["director"] == "Robert Rodriguez") & (netflix["type"] == "Movie")]
# 4
netflix[(netflix["date_added"] == "2019-07-31") | (netflix["director"] == "Robert Altman")]
# 5
search_director = ["Orson Welles", "Aditya Kripalani", "Sam Raimi"]
netflix[netflix["director"].isin(search_director)]
# 6
netflix[netflix["date_added"].between("2019-05-01", "2019-06-01")]
# 7
netflix.dropna(subset = ["director"])
# 8
netflix.drop_duplicates(subset = ["date_added"], keep = False)
关注公众号小辛到处学,发送1,获取文中的数据资源