在数据科学和分析的日常工作中,我们经常需要处理复杂的表格数据。Pandas 的 DataFrame 是 Python 中最强大的工具之一,它本质上是一个二维的表格结构,类似于我们熟知的 Excel 电子表格或 SQL 数据库中的表。但与它们不同的是,Pandas 在处理大规模数据时提供了无与伦比的灵活性和性能。
你是否曾经在面对杂乱无章的数据集时感到无从下手?或者因为不知道如何快速筛选出关键行而不得不手动复制粘贴?在这篇文章中,我们将深入探讨如何高效地处理 DataFrame 中的行和列。我们将一起学习如何选择、添加、删除以及重命名数据,并通过实际案例让你掌握这些核心技能,帮助你从繁琐的数据清洗中解放出来,专注于更有价值的数据分析工作。
为了让大家更好地理解,我们将使用一个包含球员信息的NBA数据集作为示例(当然,这些技巧适用于任何结构化数据)。让我们先来看看这个数据集大概长什么样。
> 准备工作:为了跟随后续的代码练习,建议你准备一个类似的 CSV 文件,或者直接使用 Pandas 读取任意结构化数据来进行实验。
核心概念:行与列的视角
在开始写代码之前,我们需要统一一下对 DataFrame 结构的认知。下图清晰地展示了一个典型的 DataFrame 结构。
图示:DataFrame 数据集结构
我们可以把 DataFrame 想象成一个由许多“小盒子”组成的网格:
- 列:通常代表数据的属性或变量。比如图中的“Name”(姓名)、“Team”(球队)、“Age”(年龄)等。每一列都是一个 Pandas Series,包含了该属性下的所有数据。
- 行:代表具体的观测记录或样本。图中的每一行都对应一名特定的球员及其相关信息。
- 索引:每一行最前面的那个数字(或标签),它是行的唯一标识符。默认情况下是 0, 1, 2… 但我们可以将其设置为更有意义的值(比如球员姓名)。
理解了这些基本构成单元后,让我们开始动手操作。
处理列:数据属性的管理
列操作是数据处理中最频繁的动作。无论是提取特定字段进行分析,还是根据现有数据计算新特征,都离不开对列的操作。
1. 精准选择列
面对成百上千列的数据,我们往往只对其中的几列感兴趣。不要试图处理不需要的数据,选择出相关的列可以显著提高代码的可读性和执行效率。
我们可以通过列名来轻松筛选数据。
import pandas as pd
# 读取数据
df = pd.read_csv(‘your_file.csv‘)
# 选择单列(返回 Series)
names = df[‘Name‘]
# 选择多列(返回 DataFrame)
# 建议传入一个列表,即使只有一列,也能保持 DataFrame 格式
player_info = df[[‘Name‘, ‘Age‘, ‘Team‘]]
print(player_info.head())
输出:
#### 实战见解:
- 链式操作:你可以在选择列后直接链接其他方法,例如
df[[‘Name‘, ‘Salary‘]].sort_values(‘Salary‘)。这种写法非常符合 Python 的优雅风格。 - 错误排查:如果报错 INLINECODEa220498c,请首先检查列名中是否包含多余的空格(如 INLINECODEc5404aeb),这是初学者常犯的错误。
2. 动态添加列
数据清洗中,我们经常需要根据现有数据生成新特征。比如,我们想给每个球员加一个“经验值”字段,或者将身高从公制转换为美制。
#### 方法 A:直接赋值(标量或列表)
这是最简单的方法,适用于简单的填充。
# 添加一列,所有行的值都设为 1
df[‘Experience‘] = 1
# 也可以传入一个与行数相等的列表或数组
# df[‘Random_Data‘] = range(len(df))
print(df.head())
输出:
#### 方法 B:基于现有列计算(向量化操作)
这是 Pandas 最强大的地方。我们不需要写循环,直接对整列进行数学运算。
# 假设我们有一个 ‘Salary‘ 列,想计算年薪后的税后收入(假设税率 20%)
# 注意:这只是为了演示,实际数据集中 Salary 列可能需要先清理字符串符号
if ‘Salary‘ in df.columns:
df[‘After_Tax_Salary‘] = df[‘Salary‘] * 0.8
# 或者组合字符串列
df[‘Player_Info‘] = df[‘Name‘] + " - " + df[‘Team‘]
性能提示:尽量避免使用 INLINECODE36d82c11 循环逐行赋值。利用 Pandas 的向量化操作(如 INLINECODE98d58cdc),速度通常会比循环快几十倍甚至上百倍。
3. 删除不需要的列
数据集中往往包含大量冗余信息。为了节省内存并聚焦分析目标,我们需要及时“断舍离”。
使用 drop() 方法是标准做法。
# 删除单列
# axis=1 表示沿着列的方向操作(默认是 axis=0,即行)
# inplace=True 表示直接在原数据上修改,而不是返回一个新的副本
df.drop(‘Experience‘, axis=1, inplace=True)
# 删除多列
df.drop([‘Experience‘, ‘Weight‘], axis=1, inplace=True)
print(df.head())
输出:
#### 最佳实践:
如果你不确定数据中是否存在该列,直接 INLINECODE9f73cbbe 可能会报错。为了避免程序中断,可以加上 INLINECODE44a1ac87 参数:
# 如果列存在则删除,不存在也不报错
df.drop(‘Non_Existent_Column‘, axis=1, errors=‘ignore‘, inplace=True)
处理行:数据的切片与清洗
掌握了列的操作后,让我们来看看如何处理行——也就是具体的记录。
1. 选择行:定位数据
选择行通常有两种场景:一是通过标签(比如球员名字)选择,二是通过位置索引(比如第 5 行)选择。
#### 使用 .loc[] 通过标签选择
这是最推荐的行选择方式,因为它代码可读性强,且不依赖于数据在表格中的物理位置。我们需要先设置某一列为索引。
# 将 ‘Name‘ 列设为索引,这样我们就可以通过名字找人
data = pd.read_csv("your_file.csv", index_col="Name")
# 选择单行,返回一个 Series
first_player = data.loc["Avery Bradley"]
print("单行结果:")
print(first_player)
print("
" + "="*20 + "
")
# 选择多行,返回一个 DataFrame
selected_players = data.loc[["Avery Bradley", "R.J. Hunter"]]
print("多行结果:")
print(selected_players)
输出:
#### 使用 .iloc[] 通过位置选择
有时候你只是想简单地“取前10行”或“取最后5行”,这时候不需要关心索引是什么,用位置更方便。
# 选择第一行(索引为0)
first_row = df.iloc[0]
# 选择前 5 行
top_five = df.iloc[0:5]
# 选择特定位置的行(例如第 1, 3, 5 行)
specific_rows = df.iloc[[0, 2, 4]]
#### 常见陷阱:切片的包含性
注意 INLINECODE93ceb594 的切片是左闭右开(不包含结束位),而 INLINECODE4ba6670e 的切片是左闭右闭(包含结束位)。
df.iloc[0:2]-> 取第 0, 1 行。df.loc[‘A‘:‘C‘]-> 取索引从 A 到 C 的所有行(包含 C)。
2. 添加行:扩充数据集
在现实工作中,我们很少手动“插入”一行数据(因为效率低),更多时候是将新采集的数据表 concat(拼接)到主表中。
#### 场景:追加新数据
假设我们有一个新的字典数据,代表一名新加入的球员,我们需要把他加入到现有的 DataFrame 中。
import pandas as pd
df = pd.read_csv(‘your_file.csv‘)
# 定义新行数据(注意:键名必须与 DataFrame 的列名完全一致)
new_row_data = {
‘Name‘: ‘New Player‘,
‘Team‘: ‘Boston‘,
‘Number‘: 99,
‘Position‘: ‘PG‘,
‘Age‘: 22,
‘Height‘: ‘6-0‘,
‘Weight‘: 180,
‘College‘: ‘University of Python‘,
‘Salary‘: 50000
}
# 步骤 1: 将字典转换为 DataFrame(注意要包在列表里 [new_row_data])
new_df = pd.DataFrame([new_row_data])
# 步骤 2: 使用 concat 进行拼接
# ignore_index=True 会重置索引,避免索引重复
# 注意:Pandas 新版中 append 方法已被废弃,推荐使用 concat
df = pd.concat([df, new_df], ignore_index=True)
# 查看最后几行以确认添加成功
print(df.tail(2))
输出:
#### 性能警告:
不要在循环中反复使用 pd.concat!如果需要添加几千行数据,先把所有新行收集到一个列表中,最后统一转换成 DataFrame 再进行一次 concat。这会让你的代码速度快 100 倍以上。
3. 删除行:过滤噪声
删除行通常用于清洗数据,比如去除重复项、去除空值行,或者去除特定的异常样本。
# 重新加载数据并设置 Name 为索引,方便演示
data = pd.read_csv("your_file.csv", index_col="Name")
# 删除指定的行(通过索引标签)
# 这里我们删除几位特定的球员
players_to_remove = ["Avery Bradley", "John Holland", "R.J. Hunter"]
# inplace=True 直接修改原对象
data.drop(players_to_remove, inplace=True)
print(data.head())
输出:
#### 进阶技巧:条件删除(过滤)
实际上,我们很少手动指定删除谁,而是根据条件“过滤”掉不需要的行。这虽然本质上不是删除操作,但效果是一样的。
# 比如我们只想保留年龄大于 25 岁的球员
# 这会返回一个新的 DataFrame,不满足条件的行会被“丢弃”
filtered_df = df[df[‘Age‘] > 25]
# 或者:去除 Salary 列为空值的行
df.dropna(subset=[‘Salary‘], inplace=True)
总结与进阶建议
通过这篇文章,我们从零开始构建了处理 Pandas DataFrame 行和列的知识体系。我们不仅学会了如何使用 INLINECODE6be7e177, INLINECODE17892e55, INLINECODE01dfc120 来选择数据,掌握了 INLINECODE22226a8c 和 INLINECODEba62c4fa 来添加数据,还了解了 INLINECODEbb2d7445 方法在清理数据中的妙用。
关键要点回顾:
- 列操作侧重于特征工程(计算新指标)和数据精简(丢弃无用字段)。
- 行操作侧重于数据清洗(过滤脏数据)和数据合并。
- 性能至上:尽量避免在循环中对 DataFrame 进行逐行操作,尽量使用向量化运算或批量处理方法。
- 索引的重要性:设置有意义的索引(如 ID、日期)能极大地方便我们使用
.loc进行数据检索。
下一步建议:
既然你已经掌握了行和列的基础操作,接下来可以尝试探索更复杂的数据处理任务:
- 学习如何处理缺失值(INLINECODE9a737c0b, INLINECODE580f144e)。
- 掌握 Group By 操作,学会按类别聚合数据。
- 尝试 Merge 和 Join 操作,就像 SQL 一样关联不同的数据表。
Pandas 的世界非常广阔,但掌握了这些基础后,你已经迈出了最坚实的一步。去尝试分析你自己的数据吧,如果有任何问题,欢迎随时查阅更多进阶教程。祝你在数据探索的旅程中玩得开心!