章节导读
数据选择与索引是 pandas 操作的核心。pandas 提供了多套互补的索引系统:标签索引与位置索引、基础方括号与高级查询表达式、单层与多层索引等。理解每种方式的适用场景与边界行为,是高效使用 pandas 的基础。
本章包含:
- 5.1 基础索引 – 方括号、属性访问、.loc/.at、.iloc/.iat、布尔索引与切片
- 5.2 MultiIndex 选择 – 多层索引定位、切片、IndexSlice 与 xs()
- 5.3 条件过滤与查询 – query、eval、where、mask、take、sample
- 5.4 索引调整 – reindex、set_index、reset_index、align、get、filter、select_dtypes
- 5.5 行与列的增删 – drop、pop、insert、truncate
- 5.6 链式索引与副本问题 – 视图与副本、链式赋值陷阱、Copy-on-Write
索引方式总览
| 方式 | 语法 | 适用场景 |
|---|---|---|
| 方括号 | df['col']、s[0] | 列选择、简单切片 |
| 属性访问 | df.col | 交互式探索(慎用) |
| 标签索引 | .loc[] | 按标签选择(包含端点) |
| 位置索引 | .iloc[] | 按整数位置选择(不含端点) |
| 快速标量 | .at[] / .iat[] | 单个标量快速访问 |
| 布尔索引 | df[mask] | 条件筛选 |
| 查询表达式 | df.query() | 字符串表达式过滤 |
| 表达式运算 | df.eval() | 列计算与新建 |
| 条件替换 | where() / mask() | 保留形状的值替换 |
| 交叉选择 | df.xs() | MultiIndex 剥离层级 |
| 名称过滤 | df.filter() | 按名称模式选择 |
| 类型过滤 | df.select_dtypes() | 按数据类型选择列 |
| 随机抽样 | df.sample() | 随机抽取行/列 |
| 按位置取值 | df.take() | 按整数位置数组取值 |
核心原则速查
选择(读取)语义
| 操作 | 端点 | 示例 |
|---|---|---|
.loc | 包含结束标签 | df.loc['a':'c'] |
.iloc | 不包含结束位置 | df.iloc[0:2] |
df[1:4] | 不包含结束位置 | 行 1~3 |
s['a':'c'] | 包含结束标签 | 标签 a~c |
赋值(修改)语义
| 操作 | 是否安全 | 推荐 |
|---|---|---|
df['col'][mask] = x | ❌ 链式 | 使用 .loc 替代 |
df.loc[mask, 'col'] = x | ✅ 推荐 | 总是有效 |
df.iloc[i, j] = x | ✅ 推荐 | 总是有效 |
df.col = x | ⚠️ 列名冲突时失效 | 使用 df['col'] = x |
条件组合
# 必须使用括号包裹每个条件
mask = (df['A'] > 1) & (df['B'] < 10)
# 使用集合/区间
df['城市'].isin(['北京', '上海'])
df['年龄'].between(18, 30)
# 字符串匹配
df['姓名'].str.contains('张')MultiIndex 选择
# 完整元组
df.loc[('华东', 2024)]
# 部分层级
df.loc['华东']
# 跨层切片
df.loc[pd.IndexSlice['华东':'华北', 2023:2024], :]
# 交叉选择
df.xs('华东', level='区域', drop_level=False)常见错误与规避
| 错误 | 说明 | 正确写法 |
|---|---|---|
df[['A'], ['B']] | 括号传入两个参数 | df.loc[['A'], ['B']] |
df.query('A = 1') | 单等号 = 非法 | df.query('A == 1') |
df[(df.A > 1) or (df.B < 2)] | or 不支持 | 用 |:df[(df.A>1) | (df.B<2)] |
df.loc['不存在的标签'] | 不存在抛错 | df.get / reindex |
df['col'][mask] = v | 链式赋值 | df.loc[mask, 'col'] = v |
s[0](整数索引) | 歧义 | s.iloc[0] 或 s.loc[0] |