Pandas索引实用技巧:loc、iloc、at、iat及布尔索引速查指南

作者:袖梨 2026-08-06

掌握 .loc.iloc 和布尔索引是高效使用 Pandas 的核心技能。

Pandas索引技巧:loc、iloc、at、iat及布尔索引速查指南

.loc[]— 按标签索引(Label-based)

import pandas as pdimport numpy as npdf = pd.DataFrame({    '姓名': ['张三', '李四', '王五', '赵六', '钱七'],    '年龄': [22, 25, 30, 28, 35],    '城市': ['北京', '上海', '广州', '深圳', '杭州'],    '工资': [8000, 12000, 15000, 10000, 18000]}, index=['a', 'b', 'c', 'd', 'e'])# 单行(按标签)print(df.loc['b'])           # 返回 Series# 姓名      李四# 年龄       25# 城市      上海# 工资    12000# 多行(标签列表)print(df.loc[['a', 'c', 'e']])# 标签切片(含两端!)print(df.loc['b':'d'])        # 包含 b, c, d# 行 + 列print(df.loc['b', '工资'])            # 单个值: 12000print(df.loc['b', ['姓名', '工资']])  # 行 + 列子集print(df.loc[['a', 'c'], ['姓名', '年龄']])  # 多行多列# 行 + 列切片print(df.loc['b':'d', '姓名':'城市'])  # 行切片 + 列切片# 带条件的列选择(使用布尔列表)print(df.loc[df['工资'] > 10000, ['姓名', '工资']])

.loc关键规则

规则示例
包含结束值df.loc['a':'c'] 包含 c
标签不存在会报错KeyError
返回单个值是标量df.loc['a', '年龄'] 返回 int
返回 Series单行 df.loc['a'] 或单列 df.loc[:, '年龄']

.iloc[]— 按位置索引(Integer-based)

df = pd.DataFrame({    'A': [10, 20, 30, 40, 50],    'B': [100, 200, 300, 400, 500],    'C': ['a', 'b', 'c', 'd', 'e']})# 单行(按位置)print(df.iloc[0])      # 第 0 行print(df.iloc[-1])     # 最后一行# 多行print(df.iloc[[0, 2, 4]])     # 第 0, 2, 4 行print(df.iloc[1:4])            # 第 1, 2, 3 行(不含 4!标准 Python 切片)# 行 + 列print(df.iloc[0, 1])           # 第 0 行第 1 列: 100print(df.iloc[0:3, 0:2])       # 前 3 行, 前 2 列print(df.iloc[:, :2])           # 所有行, 前 2 列print(df.iloc[1:3, :])          # 第 1-2 行, 所有列# 负数索引print(df.iloc[-3:, :])          # 最后 3 行# 等间隔取行print(df.iloc[::2])             # 每隔一行

.locvs.iloc对比

.loc[].iloc[]
索引依据标签(label)位置(integer position)
切片包含含两端不含右端(Python 语义)
行索引是数字时按索引值按位置
列选择列名列位置
布尔索引✅ 支持❌ 不支持

重要: 当索引是 0,1,2…时,.loc[1].iloc[1] 看起来一样但含义完全不同!

df = pd.DataFrame({'val': [10, 20, 30]}, index=[2, 1, 0])print(df.loc[1])    # 索引 = 1 的行 → val = 20print(df.iloc[1])   # 第 1 行 → val = 20(巧合相同)# 若 index=[5,3,1]: df.loc[1] 返回第三行,df.iloc[1] 返回第二行

at[]/iat[]— 快速标量访问

.loc/.iloc 更快,但只能取单个值

# at: 按标签取单个值print(df.at['b', '工资'])     # 12000# iat: 按位置取单个值print(df.iat[0, 3])           # 8000# 也可用于赋值df.at['b', '工资'] = 13000df.iat[0, 3] = 8500

布尔索引 — 条件筛选

基本条件

df = pd.DataFrame({    '姓名': ['张三', '李四', '王五', '赵六', '钱七'],    '年龄': [22, 25, 30, 28, 35],    '城市': ['北京', '上海', '广州', '深圳', '杭州'],    '工资': [8000, 12000, 15000, 10000, 18000]})# 单个条件print(df[df['年龄'] > 25])# 多个条件(用 & 和 |,必须加括号!)print(df[(df['年龄'] > 25) & (df['工资'] > 12000)])   # 且print(df[(df['城市'] == '北京') | (df['城市'] == '上海')])  # 或print(df[~(df['年龄'] < 30)])  # 非: 年龄 >= 30# ♀️ 常见错误: 用 and/or 代替 &/|# df[(df['年龄'] > 25) and (df['工资'] > 10000)]  ← 错误!# df[(df['年龄'] > 25) & (df['工资'] > 10000)]    ← 正确# 也可以用 .loc 配合布尔条件print(df.loc[df['工资'] > 10000])print(df.loc[df['工资'] > 10000, ['姓名', '城市']])

常见筛选方法

# isin: 值在列表中print(df[df['城市'].isin(['北京', '上海', '广州'])])# 也可以用 ~ 取反print(df[~df['城市'].isin(['深圳', '杭州'])])# between: 值在范围内print(df[df['年龄'].between(25, 30)])# 字符串条件print(df[df['姓名'].str.contains('张')])    # 名字含"张"print(df[df['城市'].str.startswith('北')])  # 城市以"北"开头print(df[df['城市'].str.len() == 2])       # 城市名长度为 2# NaN 判断print(df[df['列名'].isna()])    # 空值行print(df[df['列名'].notna()])   # 非空值行# any / all: 行列级布尔print((df > 0).any())     # 每列是否有 >0 的值print((df > 0).all())     # 每列是否所有值都 >0print((df > 0).any(axis=1))  # 每行是否有 >0 的值

query()— 字符串表达式筛选

df = pd.DataFrame({    'name': ['Alice', 'Bob', 'Charlie', 'David'],    'age': [25, 17, 35, 45],    'salary': [5000, 3000, 8000, 12000],    'city': ['NY', 'LA', 'NY', 'SF']})# 基本查询print(df.query('age > 30'))print(df.query('age > 25 and salary > 6000'))# 外部变量引用(用 @)threshold = 5000print(df.query('salary > @threshold'))# 字符串列print(df.query('city == "NY"'))print(df.query('city in ["NY", "SF"]'))# 与 .loc 配合print(df.query('age > 25')[['name', 'salary']])

where()/mask()— 条件保留/替换

df = pd.DataFrame({    'A': [1, 2, 3, 4, 5],    'B': [10, 9, 8, 7, 6]})# where: 条件为 True 保留原值,False 替换为 NaNprint(df.where(df > 3))#      A    B# 0  NaN  10.0# 1  NaN  9.0# 2  NaN  8.0# 3  4.0  7.0# 4  5.0  6.0# where + other: 不满足条件的用指定值代替print(df.where(df > 3, other=0))# mask: where 的反面(条件为 True 时替换)print(df.mask(df > 3, other=0))#    A  B# 0  1  0# 1  2  0# 2  3  0# 3  0  0# 4  0  0

列的选择与操作

# 单列: 返回 Seriesprint(df['姓名'])print(df.姓名)  # 列名是合法标识符时可用点号# 多列: 返回 DataFrame(注意双括号!)print(df[['姓名', '工资']])# 列赋值df['奖金'] = df['工资'] * 0.1               # 新增列df['总收入'] = df['工资'] + df['奖金']       # 基于现有列计算# 删除列df.drop('奖金', axis=1, inplace=True)        # axis=1 表示列df.drop(['奖金', '总收入'], axis=1, inplace=True)# 重命名列df.rename(columns={'姓名': 'name', '年龄': 'age'}, inplace=True)# 插入列(指定位置)df.insert(1, '性别', ['男', '女', '男', '男', '男'])

行操作

# 添加行df.loc['f'] = ['孙九', 27, '成都', 14000]# 通过 append 添加(创建新 DataFrame)new_row = pd.DataFrame([['周十', 32, '重庆', 16000]],                        columns=['姓名', '年龄', '城市', '工资'])df = pd.concat([df, new_row], ignore_index=True)# 删除行df.drop('f', inplace=True)            # 按标签删df.drop([0, 2], inplace=True)         # 按标签删# 按条件删行df = df[df['工资'] >= 10000]           # 保留工资 >= 10000df = df[~df['城市'].isin(['深圳'])]    # 删除深圳的行

索引筛选速查

需求代码
按标签取行列df.loc['a':'c', ['x', 'y']]
按位置取行列df.iloc[0:5, 0:3]
单个标量(快)df.at['a', 'x'] / df.iat[0, 2]
条件筛选df[df['col'] > 100]
多条件df[(df['A'] > 3) & (df['B'] < 10)]
值在列表中df[df['col'].isin([1, 2, 3])]
值在范围内df[df['col'].between(3, 8)]
字符串过滤df[df['col'].str.contains('abc')]
表达式查询df.query('A > 3 and B < 10')
选列df[['col1', 'col2']]
条件保留df.where(df > 0, other=0)

总结

相关文章

精彩推荐