DataFrame 花式索引:loc、iloc、布尔筛选一次讲清楚

📅 2026/7/4 4:22:49
DataFrame 花式索引:loc、iloc、布尔筛选一次讲清楚
DataFrame 花式索引loc、iloc、布尔筛选一次讲清楚Pandas 最难搞的不是 groupby是索引。loc、iloc、at、iat、query……光取值就一堆方法。今天一次性讲清楚再也不搞混。先分清loc 用标签iloc 用位置importpandasaspd dfpd.DataFrame({name:[张三,李四,王五,赵六],age:[25,30,22,35],city:[北京,上海,广州,深圳]},index[a,b,c,d])print(df)# name age city# a 张三 25 北京# b 李四 30 上海# c 王五 22 广州# d 赵六 35 深圳# loc用标签名索引名 a/b/c/d列名 name/age/cityprint(df.loc[b])# 第 b 行print(df.loc[b,age])# b 行age 列 → 30print(df.loc[[a,c]])# 多行print(df.loc[a:c,name:age])# 行切片列切片标签切片包含末端# iloc用整数位置和 Python 列表一样从0开始print(df.iloc[1])# 第2行print(df.iloc[1,0])# 第2行第1列 → 李四print(df.iloc[:2,1:])# 前2行第2列以后核心区别就一句loc 看标签名iloc 看位置编号。loc 切片注意包含末端# Python 列表切片不含末端lst[1,2,3,4,5]print(lst[1:3])# [2, 3]# Pandas loc 标签切片包含末端print(df.loc[a:c])# a, b, c 三行都出来这个区别坑过无数人。布尔筛选最实用的取值方式dfpd.DataFrame({name:[张三,李四,王五,赵六,孙七],age:[25,30,22,35,28],city:[北京,上海,广州,深圳,北京],score:[85,92,78,95,88]})# 单条件print(df[df[age]25])# 多条件用 | ~print(df[(df[age]25)(df[score]90)])# age25 且 score≥90print(df[(df[city]北京)|(df[city]上海)])# isin多个值匹配print(df[df[city].isin([北京,上海])])# ~ 取反print(df[~df[city].isin([北京])])# between范围筛选print(df[df[age].between(25,30)])# str 方法字符串筛选print(df[df[name].str.contains(三)])print(df[df[name].str.startswith(张)])query()更接近自然语言# 条件多的时候query 可读性更好resultdf.query(age 25 and score 80)print(result)# 引用外部变量用 min_age25resultdf.query(age min_age)# 字符串比较resultdf.query(city in [北京, 上海])行列同时筛选# loc 布尔选某些列按条件筛行resultdf.loc[df[score]80,[name,score]]print(result)# iloc 布尔maskdf[score]80resultdf.iloc[mask.values,[0,3]]# 选 name 和 score 列print(result)实战学生成绩分析importpandasaspdimportnumpyasnp np.random.seed(42)studentspd.DataFrame({name:[f学生{i:02d}foriinrange(1,31)],class:np.random.choice([A班,B班,C班],30),math:np.random.randint(40,100,30),english:np.random.randint(40,100,30),python:np.random.randint(40,100,30),})# 定位数学最高分的学生top_mathstudents.loc[students[math].idxmax()]print(f数学最高{top_math[name]}{top_math[math]}分)# 找出 A 班 Python 成绩 80 的学生a_beststudents[(students[class]A班)(students[python]80)]print(fA班 Python 80 的有{len(a_best)}人)# 前10名按 Python 成绩排top10students.nlargest(10,python)[[name,class,python]]print(top10)# 用 loc 批量修改给 Python 60 的学生加10分假设平时分conditionstudents[python]60students.loc[condition,python]10print(f加分后不及格人数{(students[python]60).sum()})新手常见坑坑1loc 和 iloc 用混# 假设索引是字符串 a,b,c# df.iloc[a] # 报错iloc 要整数# df.loc[0] # 索引里没有0也报错除非索引正好是整数坑2链式索引# ❌ 链式索引可能产生副本df[df[age]25][age]30# 修改可能不生效# ✅ 用 locdf.loc[df[age]25,age]30坑3布尔筛选的括号# ❌ 不加括号运算符优先级出错# df[df[age] 25 df[score] 80]# ✅ 每个条件都要括号df[(df[age]25)(df[score]80)]动手试试创建一个 10 行的员工表姓名、部门、薪资筛选出薪资前 3 的员工用 query() 筛选出年龄在 25-35 之间的所有行用 loc 把薪资低于 5000 的行统一调薪 1000写在最后记住三句话loc 用标签iloc 用位置筛选用布尔索引多条件加括号修改数据用 loc别用链式索引下一篇聊数据清洗——缺失值、重复值、异常值真实数据从来不是干净的。