准备工作:创建一个示例 DataFrame
为了方便演示,我们先创建一个示例 DataFrame。

import pandas as pd
import numpy as np
# 创建一个字典
data = {
'姓名': ['张三', '李四', '王五', '赵六', '钱七'],
'年龄': [25, 32, 28, 45, 22],
'城市': ['北京', '上海', '广州', '北京', '深圳'],
'薪资': [12000, 15000, 13000, 20000, 11000]
}
# 创建 DataFrame
df = pd.DataFrame(data)
# 设置 '姓名' 列为索引
df_indexed = df.set_index('姓名')
print("--- 原始 DataFrame ---")
print(df)
print("\n--- 设置索引后的 DataFrame ---")
print(df_indexed)
使用 [] 方括号(最常用,但需注意)
方括号是取值最直接的方式,但它的行为根据传入参数的不同而变化,容易混淆。
单列取值
- 传入列名:返回一个 Pandas Series。
- 传入一个列名的列表:返回一个新的 DataFrame。
# 取 '年龄' 列,返回一个 Series age_series = df['年龄'] print(type(age_series)) # print(age_series) # 取 '年龄' 和 '城市' 多列,必须传入列表,返回一个 DataFrame subset_df = df[['年龄', '城市']] print(type(subset_df)) # print(subset_df)
行切片
- 传入一个整数或切片 :这是
[]方括号为数不多可以明确用于行切片的场景,它基于整数位置进行切片,类似于 Python 列表。
# 取第 2 行到第 4 行(不包括第 4 行),返回一个 DataFrame # 注意:索引从 0 开始 rows_slice = df[1:4] print(rows_slice)
⚠️ 重要提示:
df['年龄']和df[1:4]看起来相似,但前者取列,后者取行,这是[]方括号最让人困惑的地方。
.loc 标签索引(推荐)
.loc 是基于 的索引器,这是最推荐、最清晰、最不容易出错的方法,它的语法是 .loc[行标签, 列标签]。
单行取值
# 取索引为 '李四' 的整行,返回一个 Series li_si_row = df_indexed.loc['李四'] print(li_si_row)
多行取值
# 取 '李四' 和 '王五' 的行,返回一个 DataFrame multi_rows = df_indexed.loc[['李四', '王五']] print(multi_rows)
单列取值
# 取 '城市' 列,返回一个 Series city_col = df_indexed.loc[:, '城市'] print(city_col) # 等价于 df_indexed['城市']
多列取值
# 取 '年龄' 和 '薪资' 列,返回一个 DataFrame multi_cols = df_indexed.loc[:, ['年龄', '薪资']] print(multi_cols)
同时选择多行和多列(最强大的用法)
# 取 '李四' 和 '王五' 的 '年龄' 和 '城市' 信息 subset = df_indexed.loc[['李四', '王五'], ['年龄', '城市']] print(subset)
结合条件筛选(.loc 的精髓)
这是 .loc 最强大的功能,可以轻松实现 SQL 中的 WHERE 子句功能。

# 找出年龄大于 30 的人 age_over_30 = df.loc[df['年龄'] > 30] print(age_over_30) # 找出在北京且薪资高于 15000 的人 beijing_high_salary = df.loc[(df['城市'] == '北京') & (df['薪资'] > 15000)] print(beijing_high_salary) # 使用 `|` (或), `&` (与), `~` (非) # 找出年龄小于 25 或者城市是上海的人 young_or_shanghai = df.loc[(df['年龄'] < 25) | (df['城市'] == '上海')] print(young_or_shanghai)
.iloc 位置索引
.iloc 是基于整数位置 的索引器,类似于 NumPy 数组的索引,它的语法是 .iloc[行位置, 列位置],位置从 0 开始。
单行取值
# 取第 2 行(位置为 1)的整行,返回一个 Series row_iloc = df.iloc[1] print(row_iloc)
多行取值
# 取第 1 行到第 3 行(位置 1 到 3,不包括 3) rows_iloc_slice = df.iloc[1:3] print(rows_iloc_slice)
单列取值
# 取第 2 列(位置为 1)的整列,返回一个 Series col_iloc = df.iloc[:, 1] print(col_iloc)
多列取值
# 取第 0 列和第 2 列 cols_iloc = df.iloc[:, [0, 2]] print(cols_iloc)
同时选择多行和多列
# 取第 1, 3 行和第 0, 2 列 subset_iloc = df.iloc[[1, 3], [0, 2]] print(subset_iloc)
.at 和 .iat 快速标量访问
当你只需要 DataFrame 中单个值(标量)时,使用 .at 和 .iat 比 .loc 和 .iloc 更快。
.at:基于,快速访问单个值。.iat:基于整数位置,快速访问单个值。
# 使用 .at 获取 '李四' 的 '薪资'
salary_li_si_at = df_indexed.at['李四', '薪资']
print(f"使用 .at 获取的薪资: {salary_li_si_at}")
# 使用 .iat 获取第 2 行(位置 1)第 3 列(位置 2)的值
salary_li_si_iat = df.iat[1, 2]
print(f"使用 .iat 获取的薪资: {salary_li_si_iat}")
query() 方法(优雅的条件查询)
当你的筛选条件非常复杂时,query() 方法提供了一种非常 SQL 风格且易读的语法。
# 使用 query() 找出年龄大于 30 且城市是北京的人
# 注意:列名可以直接使用,不需要 df['列名'] 的形式
result_query = df.query('年龄 > 30 and 城市 == "北京"')
print(result_query)
# 也可以使用变量
min_age = 30
city_name = '北京'
result_query_var = df.query(f'年龄 > {min_age} and 城市 == @city_name')
print(result_query_var)
总结与最佳实践
| 方法 | 全称 | 索引依据 | 主要用途 | 示例 |
|---|---|---|---|---|
[] |
Bracket | 混合(列名/行切片) | 快速取单列/多列、行切片 | df['年龄'], df[1:4] |
.loc |
Location | (推荐) 基于标签的精确行、列、条件筛选 | df.loc[df['年龄'] > 30, ['姓名', '薪资']] |
|
.iloc |
Integer Location | 整数位置 | 基于位置的行、列切片(类似 NumPy) | df.iloc[[0, 2], 1:3] |
.at |
At | 快速访问单个标签值 | df.at['李四', '年龄'] |
|
.iat |
Integer At | 整数位置 | 快速访问单个位置值 | df.iat[1, 2] |
query() |
Query | 列名/变量 | 优雅、可读性高的复杂条件查询 | df.query('年龄 > 30 and 城市 == "北京"') |
最佳实践建议:
- 日常使用
.loc:绝大多数情况下,优先使用.loc进行取值和筛选,因为它清晰、明确,不易出错。 - 明确你的意图:
- 如果你知道你要取的行或列的名称/标签,用
.loc。 - 如果你只知道它们在 DataFrame 中的第几个(位置),用
.iloc。
- 如果你知道你要取的行或列的名称/标签,用
- 避免使用
[]进行复杂操作:[]的行为容易混淆,除了简单的单列取值和行切片外,尽量使用.loc和.iloc。 - 快速取单值用
.at/.iat:在循环中需要反复访问单个值时,它们性能更好。 - 复杂条件用
query():当条件字符串很长时,query()的语法能让代码更整洁易读。

