第147集:数据筛选与排序
一、课程概述
在数据分析中,数据筛选与排序是最基础也是最常用的操作。通过筛选,我们可以从海量数据中提取出符合特定条件的子集;通过排序,我们可以按照特定规则重新组织数据,使分析更加直观和高效。本集将详细介绍Pandas中数据筛选与排序的各种方法和技巧。
二、数据筛选
1. 条件筛选
1.1 基本条件筛选
使用布尔索引进行条件筛选是最基础的筛选方式:
import pandas as pd
# 创建示例数据
data = {
'姓名': ['张三', '李四', '王五', '赵六', '钱七'],
'年龄': [25, 28, 26, 30, 24],
'性别': ['男', '男', '女', '男', '女'],
'成绩': [88, 92, 85, 95, 89],
'班级': ['一班', '二班', '一班', '二班', '一班']
}
df = pd.DataFrame(data)
# 筛选成绩大于90分的学生
high_score = df[df['成绩'] > 90]
print("成绩大于90分的学生:")
print(high_score)1.2 多条件筛选
使用&(与)、|(或)、~(非)运算符组合多个条件:
# 筛选一班且成绩大于85分的学生
class1_high = df[(df['班级'] == '一班') & (df['成绩'] > 85)]
print("一班且成绩大于85分的学生:")
print(class1_high)
# 筛选成绩大于90分或年龄小于25岁的学生
score_or_age = df[(df['成绩'] > 90) | (df['年龄'] < 25)]
print("成绩大于90分或年龄小于25岁的学生:")
print(score_or_age)
# 筛选不是二班的学生
not_class2 = df[~(df['班级'] == '二班')]
print("不是二班的学生:")
print(not_class2)2. isin()方法
用于筛选包含在指定列表中的数据:
# 筛选姓名为张三、李四、王五的学生
selected_names = df[df['姓名'].isin(['张三', '李四', '王五'])]
print("指定姓名的学生:")
print(selected_names)
# 筛选班级为一班或三班的学生(三班不存在)
selected_classes = df[df['班级'].isin(['一班', '三班'])]
print("指定班级的学生:")
print(selected_classes)3. between()方法
用于筛选数值在指定范围内的数据:
# 筛选成绩在85到90之间的学生(包含边界值)
score_between = df[df['成绩'].between(85, 90)]
print("成绩在85到90之间的学生:")
print(score_between)
# 筛选年龄在25到28之间的学生(不包含边界值)
age_between = df[df['年龄'].between(25, 28, inclusive='neither')]
print("年龄在25到28之间的学生(不包含边界值):")
print(age_between)4. str方法结合筛选
对于字符串类型的数据,可以使用str方法进行复杂筛选:
# 创建包含更多字符串数据的示例
data_with_str = {
'姓名': ['张三', '李四', '王五', '赵六', '钱七'],
'邮箱': ['zhangsan@example.com', 'lisi@test.com', 'wangwu@gmail.com', 'zhaoliu@example.com', 'qianqi@test.com'],
'专业': ['计算机科学', '软件工程', '数据科学', '计算机科学', '软件工程']
}
df_str = pd.DataFrame(data_with_str)
# 筛选邮箱包含'example'的学生
email_example = df_str[df_str['邮箱'].str.contains('example')]
print("邮箱包含'example'的学生:")
print(email_example)
# 筛选专业以'计算机'开头的学生
major_cs = df_str[df_str['专业'].str.startswith('计算机')]
print("专业以'计算机'开头的学生:")
print(major_cs)
# 筛选专业以'工程'结尾的学生
major_eng = df_str[df_str['专业'].str.endswith('工程')]
print("专业以'工程'结尾的学生:")
print(major_eng)5. query()方法
使用类似SQL的语法进行筛选,代码更简洁:
# 使用query筛选成绩大于90分的学生
high_score_query = df.query('成绩 > 90')
print("使用query筛选成绩大于90分的学生:")
print(high_score_query)
# 使用query筛选一班且成绩大于85分的学生
class1_high_query = df.query('班级 == "一班" & 成绩 > 85')
print("使用query筛选一班且成绩大于85分的学生:")
print(class1_high_query)
# 使用变量进行筛选
min_score = 88
high_score_var = df.query('成绩 > @min_score')
print(f"使用query筛选成绩大于{min_score}分的学生:")
print(high_score_var)三、数据排序
1. sort_values()方法
按照指定列的值进行排序:
# 按照成绩升序排序
sorted_by_score = df.sort_values('成绩')
print("按成绩升序排序:")
print(sorted_by_score)
# 按照成绩降序排序
sorted_by_score_desc = df.sort_values('成绩', ascending=False)
print("按成绩降序排序:")
print(sorted_by_score_desc)2. 多列排序
按照多个列的值进行排序:
# 先按班级排序,再按成绩降序排序
sorted_by_class_score = df.sort_values(['班级', '成绩'], ascending=[True, False])
print("按班级升序、成绩降序排序:")
print(sorted_by_class_score)3. sort_index()方法
按照索引进行排序:
# 创建一个索引无序的DataFrame
df_index = df.set_index('姓名')
df_shuffled = df_index.sample(frac=1)
print("索引无序的DataFrame:")
print(df_shuffled)
# 按索引升序排序
sorted_by_index = df_shuffled.sort_index()
print("按索引升序排序:")
print(sorted_by_index)
# 按索引降序排序
sorted_by_index_desc = df_shuffled.sort_index(ascending=False)
print("按索引降序排序:")
print(sorted_by_index_desc)4. 排名
使用rank()方法对数据进行排名:
# 添加排名列
df['成绩排名'] = df['成绩'].rank(ascending=False)
print("添加成绩排名:")
print(df)
# 处理并列排名(使用不同的排名方法)
# average:平均排名(默认)
# min:最小排名
# max:最大排名
# first:按出现顺序排名
# dense:密集排名
df['成绩排名_min'] = df['成绩'].rank(ascending=False, method='min')
df['成绩排名_first'] = df['成绩'].rank(ascending=False, method='first')
print("不同排名方法的结果:")
print(df[['姓名', '成绩', '成绩排名', '成绩排名_min', '成绩排名_first']])四、综合案例:学生成绩分析
案例描述
现有一个学生成绩数据集,包含学生的基本信息和各科成绩。需要进行以下分析:
- 筛选出数学成绩大于80分且英语成绩大于75分的学生
- 对筛选后的学生按总分降序排序
- 为排序后的学生添加排名
实现代码
# 创建学生成绩数据集
student_scores = {
'学号': ['S001', 'S002', 'S003', 'S004', 'S005', 'S006', 'S007', 'S008'],
'姓名': ['张三', '李四', '王五', '赵六', '钱七', '孙八', '周九', '吴十'],
'班级': ['一班', '一班', '二班', '二班', '三班', '三班', '四班', '四班'],
'数学': [85, 92, 78, 95, 88, 76, 90, 82],
'英语': [80, 88, 76, 92, 85, 74, 89, 77],
'语文': [90, 85, 82, 88, 92, 78, 85, 80]
}
scores_df = pd.DataFrame(student_scores)
# 计算总分
scores_df['总分'] = scores_df['数学'] + scores_df['英语'] + scores_df['语文']
print("原始学生成绩数据:")
print(scores_df)
# 1. 筛选数学成绩大于80分且英语成绩大于75分的学生
filtered_students = scores_df[(scores_df['数学'] > 80) & (scores_df['英语'] > 75)]
# 2. 按总分降序排序
sorted_students = filtered_students.sort_values('总分', ascending=False)
# 3. 添加排名
sorted_students['排名'] = sorted_students['总分'].rank(ascending=False, method='min')
print("\n筛选并排序后的学生成绩:")
print(sorted_students[['学号', '姓名', '班级', '数学', '英语', '语文', '总分', '排名']])
# 分析:找出总分最高的学生
top_student = sorted_students.loc[sorted_students['排名'] == 1]
print("\n总分最高的学生:")
print(top_student[['姓名', '班级', '总分', '排名']])五、注意事项
条件筛选时的括号:在进行多条件筛选时,每个条件都需要用括号括起来,否则可能会因运算符优先级问题导致错误。
字符串比较:在Python 3中,字符串比较区分大小写,使用str方法时要注意。
NaN值处理:在筛选和排序时,NaN值通常会被放在最后。
大型数据集:对于大型数据集,使用query()方法可以提高筛选效率。
排名方法选择:根据实际需求选择合适的排名方法,特别是在处理并列数据时。
六、总结
本集详细介绍了Pandas中数据筛选与排序的各种方法和技巧,包括:
数据筛选:
- 基本条件筛选
- 多条件筛选
- isin()方法
- between()方法
- str方法结合筛选
- query()方法
数据排序:
- sort_values()方法(单列和多列排序)
- sort_index()方法
- rank()方法(不同排名方式)
综合案例:学生成绩分析,综合运用了筛选、排序和排名功能。
通过本集的学习,您已经掌握了Pandas中数据筛选与排序的核心技能,这些技能将在数据分析的各个阶段发挥重要作用。
七、练习
创建一个包含员工信息的DataFrame,包括姓名、部门、职位、工资等字段,然后:
- 筛选工资大于8000的员工
- 筛选技术部且职位为工程师的员工
- 按工资降序排序,并添加排名
针对学生成绩数据集,尝试:
- 筛选出至少有一门科目不及格(<60分)的学生
- 按班级分组后,对每个班级的学生按总分排序
- 计算每个学生的平均分,并按平均分排名
通过这些练习,您可以进一步巩固本集所学的知识。
下一集预告:数据分组与聚合