Pandas 核心操作指南:索引、筛选、赋值与函数应用
Pandas 核心操作指南索引、筛选、赋值与函数应用在数据分析和数据科学领域pandas是 Python 生态中不可或缺的库。它基于 NumPy 构建提供了高性能的DataFrame和Series数据结构以及丰富的数据操作接口。本文将系统介绍 pandas 中最常用、最容易出错的核心操作包括索引选择loc/iloc、列操作、条件筛选、apply函数以及如何避免常见的SettingWithCopyWarning。所有知识点均配有可运行代码示例。1. 认识 DataFrame 与 SeriesDataFrame二维表格有行索引默认为 0,1,2…和列名。Series一维带标签的数组。举个例子可以把 DataFrame 想象成一张学生成绩表。行索引学生的学号或姓名如“张三”、“李四”列名科目如“语文”、“数学”那么每一列如“数学”列是一个 Series它的索引就是所有学生的名字行索引值是对应的数学成绩。每一行如“张三”这一行如果单独取出来也是一个 Series它的索引就是科目名称列名值是张三各科的成绩。代码验证importpandasaspd# 创建成绩表 DataFrame行索引为学生姓名dfpd.DataFrame({语文:[85,90,78],数学:[92,88,95],英语:[88,85,80]},index[张三,李四,王五])print(成绩表 DataFrame:)print(df)输出语文 数学 英语 张三 85 92 88 李四 90 88 85 王五 78 95 80取一列数学→ Seriesmath_coldf[数学]print(\n取“数学”列:)print(math_col)print(该 Series 的索引即学生姓名:,math_col.index.tolist())print(值:,math_col.values)输出取“数学”列: 张三 92 李四 88 王五 95 Name: 数学, dtype: int64 该 Series 的索引即学生姓名: [张三, 李四, 王五] 值: [92 88 95]取一行李四→ Seriesli_rowdf.loc[李四]print(\n取“李四”这一行:)print(li_row)print(该 Series 的索引即科目:,li_row.index.tolist())print(值:,li_row.values)输出取“李四”这一行: 语文 90 数学 88 英语 85 Name: 李四, dtype: int64 该 Series 的索引即科目: [语文, 数学, 英语] 值: [90 88 85]总结列 → Series索引 原 DataFrame 的行索引学生名值 该科成绩。行 → Series索引 原 DataFrame 的列名科目值 该生各科成绩。通过这个成绩表的例子就能直观理解无论取一列还是取一行返回的都是 Series只是它们的索引含义不同。2. 数据选择loc与ilocpandas 提供了两种主要的索引方法标签索引loc和整数位置索引iloc。2.1loc基于标签行名/列名格式df.loc[行选择, 列选择]行选择单标签、标签列表、标签切片包含终点、布尔条件、可调用对象列选择单列字符串、多列列表、列切片col1:col3# 选取单行结果为 Seriesprint(df.loc[李四])# 索引为 李四 的行# 选取多行结果为 DataFrameprint(df.loc[张三:王五])# 行索引 张三, 李四, 王五注意包含终点# 选取特定列print(df.loc[:,[语文,数学]])# 所有行语文和数学列# 布尔条件见第4节print(df.loc[df[数学]90,:])2.2iloc基于整数位置0-based格式df.iloc[行位置, 列位置]行/列选择整数、整数列表、整数切片不包含终点# 取第二行第三列的值行索引1列索引2print(df.iloc[1,2])# 李四的英语成绩 85# 取前2行第1列和第3列列索引0和2print(df.iloc[0:2,[0,2]])# 行0,1列0(语文)和2(英语)# 行切片左闭右开print(df.iloc[0:2,:])2.3 直接使用df[]的快速方式# 选择单列 → Seriesdf[数学]# 选择多列 → DataFramedf[[语文,数学]]# 行切片基于位置左闭右开**不能同时选列**df[0:2]# 前2行所有列3. 添加/删除列3.1 添加新列可以通过常量、列表或基于已有列计算添加。# 常量列df[新常量]1# 列表长度必须匹配df[新列表][100,200,300]# 基于现有列计算df[总分]df[语文]df[数学]df[英语]# 使用 np.where 条件赋值importnumpyasnp df[数学优秀]np.where(df[数学]90,是,否)# 使用 apply按列逐元素df[语文等级]df[语文].apply(lambdax:优秀ifx90else良好)3.2 批量添加列assignassign返回一个新的 DataFrame不修改原对象可以同时添加多列。df_newdf.assign(总分df[语文]df[数学]df[英语],平均分(df[语文]df[数学]df[英语])/3)3.3 删除列drop# 删除单列df_droppeddf.drop(新常量,axis1)# 删除多列df_droppeddf.drop([新列表,语文等级],axis1)# 原地删除df.drop(数学优秀,axis1,inplaceTrue)注意inplaceTrue会直接修改原 DataFrame谨慎使用。4. 条件筛选与赋值4.1 布尔索引筛选行# 数学大于90的行df[df[数学]90]# 多个条件 表示且| 表示或df[(df[数学]90)(df[语文]85)]4.2 条件赋值最常见的需求根据条件给新列赋值。推荐使用loc一次性完成避免SettingWithCopyWarning。# 正确做法使用 locdf.loc[df[数学]90,数学等级]Adf.loc[df[数学]90,数学等级]B# 也可以使用 np.wheredf[数学等级2]np.where(df[数学]90,A,B)5. 数值运算与排序5.1 常用数值运算DataFrame 支持直接使用运算符,-,*,/等也支持统计方法。# 列间运算df[总分]df[语文]df[数学]df[英语]# 统计描述df[数学].mean()df[语文].max()df[[数学,英语]].sum()# 各列求和5.2 排序# 按数学成绩升序排序返回新 DataFramedf_sorteddf.sort_values(数学)# 降序df_sorteddf.sort_values(数学,ascendingFalse)# 多列排序df_sorteddf.sort_values([数学,语文],ascending[False,True])# 原地排序df.sort_values(数学,inplaceTrue)6.apply函数灵活应用apply是 pandas 中最强大的函数之一可以沿 DataFrame 的轴行或列应用一个函数。6.1 在 Series 上使用apply逐元素处理# 提取姓名字符串长度此处用成绩表示例可改为其他df[数学的十分之一]df[数学].apply(lambdax:x/10)# 用 lambda 定义复杂逻辑df[数学是否优秀]df[数学].apply(lambdax:优秀ifx90else普通)6.2 在 DataFrame 上使用applyaxis0默认将每一列作为 Series 传入函数返回一个值或 Series。axis1将每一行作为 Series 传入函数。# axis0计算每列最大值与最小值的差resultdf[[语文,数学,英语]].apply(lambdax:x.max()-x.min(),axis0)print(result)# 语文、数学、英语各自的极差# axis1计算每行总分其实直接用 sum 更简单这里演示用法defrow_sum(row):returnrow[语文]row[数学]row[英语]df[总分]df.apply(row_sum,axis1)7. 视图与复制警告SettingWithCopyWarning这是 pandas 初学者最常遇到的警告。它的本质是对可能是视图原数据的切片的 DataFrame 进行赋值操作时pandas 无法确定你是想修改原数据还是临时副本因此发出警告。7.1 触发警告的典型场景# 危险的链式索引Chained Indexingdf[df[数学]90][新列]100# 会触发警告7.2 安全做法方法一使用loc一次性赋值推荐df.loc[df[数学]90,新列]100方法二显式创建副本subsetdf[df[数学]90].copy()subset[新列]1007.3 为什么会出现视图某些操作如df[condition]返回的是原数据的一个视图视图修改会影响原数据某些返回的是副本。为了避免不确定性始终使用loc进行条件赋值或者主动.copy()。经验法则只要看到SettingWithCopyWarning就用loc重写赋值语句。8. 综合示例下面结合所有知识点完成一个数据处理流程importpandasaspdimportnumpyasnp# 创建成绩表dfpd.DataFrame({语文:[85,90,78,92],数学:[92,88,95,89],英语:[88,85,80,91]},index[张三,李四,王五,赵六])# 1. 添加总分列df[总分]df[语文]df[数学]df[英语]# 2. 使用 np.where 标记数学是否优秀df[数学优秀]np.where(df[数学]90,是,否)# 3. 使用 apply 计算每行平均分df[平均分]df[[语文,数学,英语]].apply(lambdax:x.mean(),axis1)# 4. 按总分排序降序df_sorteddf.sort_values(总分,ascendingFalse)# 5. 筛选出数学优秀且总分大于270的行high_achieversdf_sorted.loc[(df_sorted[数学优秀]是)(df_sorted[总分]270),:]# 6. 安全赋值给这些学生加荣誉标记df.loc[high_achievers.index,荣誉]优秀学生print(df)小结认识数据结构DataFrame 是二维表格列是 Series索引为行索引行提取后也是 Series索引为列名。通过成绩表的例子理解行列索引的区别。索引选择loc基于标签含终点iloc基于整数位置不含终点。简单场景可用df[列名]或df[行切片]。列操作直接赋值、assign、drop。条件筛选与赋值布尔索引配合loc是最安全的方式务必避免链式索引。applySeries 上逐元素处理DataFrame 上可沿行或列应用函数。视图警告始终使用loc[condition, col] value或显式.copy()。掌握 pandas 的核心操作能够高效地完成数据清洗、转换和分析。后续可以进一步学习分组聚合groupby、合并merge、透视表pivot_table等高级功能。建议读者跟着本文示例敲一遍代码加深对索引和赋值的理解。