Pandas 数据选择与定位 (Selection Indexing) 速查表
Pandas 数据选择与定位 (Selection Indexing) 速查表适用版本: Pandas 1.x / 2.x核心概念:Selection (选择): 基于标签或布尔条件筛选数据。Indexing (索引): 基于位置或标签快速访问数据。View vs Copy: 链式赋值Chained Assignment可能导致SettingWithCopyWarning推荐使用.loc/.iloc。1. 读取数据与基础查看目的: 加载数据并了解其结构为选择做准备。importpandasaspdimportnumpyasnp# --- 创建示例 DataFrame ---data{name:[Alice,Bob,Charlie,David,Eva],age:[25,30,35,40,30],city:[NYC,LA,NYC,SF,LA],salary:[70000,80000,120000,90000,75000]}dfpd.DataFrame(data)df.set_index(name,inplaceTrue)# 将 name 设为索引# --- 基础查看 ---df.head()# 查看前5行df.tail(3)# 查看后3行df.shape# (行数, 列数)df.columns# 列名列表df.index# 索引对象df.info()# 数据类型和内存占用df.describe()# 数值列统计摘要2. 选择列 (Selecting Columns)目的: 提取单个或多个列。操作代码示例返回类型说明单列df[age]pd.Series最常用方式单列 (属性式)df.agepd.Series仅在列名无空格/特殊字符时可用多列df[[age, salary]]pd.DataFrame传入列名列表列名过滤df.filter(likea)pd.DataFrame选择列名包含 ‘a’ 的列按正则选列df.filter(regex^s)pd.DataFrame选择以 ‘s’ 开头的列3. 基于标签选择 (.loc)目的: 通过行标签 (Index Label)和列名进行选择。推荐用法。# 语法: df.loc[row_label(s), column_label(s)]# --- 行选择 ---df.loc[Alice]# 选择单行 (Series)df.loc[[Alice,Bob]]# 选择多行 (DataFrame)# --- 行列同时选择 ---df.loc[Alice,age]# 标量值 (Scalar)df.loc[Alice,[age,city]]# 单行多列 (Series)# --- 切片 (包含末端) ---df.loc[Alice:David,age:city]# --- 布尔索引 (Boolean Indexing) ---df.loc[df[age]30]# 年龄大于30的所有行df.loc[df[city]NYC,salary]# NYC员工的薪水df.loc[(df[age]30)(df[salary]100000)]# 多条件 (, |, ~)4. 基于位置选择 (.iloc)目的: 通过整数位置 (Integer Position)进行选择从 0 开始。# 语法: df.iloc[row_position(s), column_position(s)]# --- 行选择 ---df.iloc[0]# 第一行 (Series)df.iloc[[0,2]]# 第1和第3行 (DataFrame)# --- 行列同时选择 ---df.iloc[0,1]# 第1行第2列的值df.iloc[0:2,1:3]# 行切片(不含2)和列切片(不含3)# --- 使用列表/数组 ---df.iloc[np.arange(3),[0,2]]# --- 负索引 ---df.iloc[-1]# 最后一行5. .loc 与 .iloc 对比 (Cheat Sheet)特性.loc.iloc访问方式标签 (Label-based)位置 (Position-based)切片行为包含末端(A:C)不包含末端(0:2)索引示例df.loc[Alice, age]df.iloc[0, 1]布尔数组支持 (df.loc[bool_series])不支持推荐度⭐⭐⭐⭐⭐ (首选更安全)⭐⭐⭐⭐ (处理位置数据时用)6. 条件筛选与布尔索引 (Boolean Mask)目的: 根据复杂逻辑过滤数据。# --- 基本比较 ---df[df[age]30]df[df[salary].between(70000,90000)]# --- isin() 成员检查 ---df[df[city].isin([NYC,LA])]# --- 字符串操作 (str accessor) ---df[df[city].str.startswith(N)]df[df[city].str.contains(Y,naFalse)]# naFalse 处理 NaN# --- 缺失值筛选 ---df[df[salary].isna()]# 选择 salary 为空的行df[df[salary].notna()]# 选择 salary 非空的行# --- 组合条件 ---# 注意每个条件必须用括号括起来并用 (AND), | (OR), ~ (NOT)condition(df[age]30)(df[city]!SF)df.loc[condition]7. 赋值与修改数据 (Assignment)目的: 安全地修改 DataFrame 中的值。# --- 直接赋值 (广播机制) ---df[bonus]1000# 新增一列所有值为1000df[total_comp]df[salary]df[bonus]# --- 使用 .loc 赋值 (推荐) ---df.loc[Alice,salary]75000# 修改单个值df.loc[df[age]35,bonus]5000# 条件更新# --- 避免链式赋值 (Chained Assignment) ---# ❌ 不推荐 (可能产生 Warning 或不生效):df[df[age]30][bonus]3000# ✅ 推荐:df.loc[df[age]30,bonus]30008. 其他高级选择技巧# --- at / iat (快速标量访问) ---df.at[Alice,age]# 等同于 df.loc[Alice, age]但速度更快df.iat[0,1]# 等同于 df.iloc[0, 1]但速度更快# --- query() 方法 (类 SQL 语法) ---df.query(age 30 and city NYC)df.query(age in [30, 35])# --- where() 方法 (保留原结构) ---# 不满足条件的值会被替换为 NaN (或指定值)df.where(df[age]30,other0)# --- lookup() (已弃用建议用 .loc) ---# df.lookup(row_labels, col_labels) - 使用 df.loc[row_labels, col_labels]9. 常见错误与解决方案 (Troubleshooting)问题现象原因分析解决方案SettingWithCopyWarning使用了链式索引 (e.g.,df[df.A0][B]1)改用.loc:df.loc[df.A0, B]1KeyError: ‘column_name’列名不存在或拼写错误检查df.columns.tolist()切片结果不符合预期混淆了.loc(含尾) 和.iloc(不含尾)明确使用场景优先用.loc条件过滤失效忘记给多条件加括号( )(cond1) (cond2)修改了原始数据Pandas 默认是 View 还是 Copy 不明确如需副本显式使用df.copy() 最佳实践总结 (Best Practices)首选.loc: 除非明确需要按位置索引否则一律使用.loc进行读写避免歧义。警惕链式赋值: 永远不要在一个语句中同时使用[]两次进行修改。使用副本: 如果需要修改数据的子集而不影响原 DataFrame请先sub_df df.loc[...].copy()。性能: 对于循环内的单个元素访问使用at/iat代替loc/iloc。