Pandas 数据结构 – DataFrame:数据处理的瑞士军刀
在数据科学和分析领域,Pandas 是最常用、最核心的工具之一。它不仅让数据处理变得高效,还让代码更具可读性和表达力。而其中最核心的结构,就是 DataFrame —— 一个二维、可变大小、带标签的表格型数据结构。它就像一张 Excel 表格,但功能更强大,也更适合编程自动化处理。
如果你曾经用过 Excel 来整理销售数据、用户信息或实验记录,那么你对“表格”并不陌生。Pandas 的 DataFrame 正是这种思维的编程实现。它将行(记录)和列(字段)完美结合,支持复杂操作,如合并、分组、筛选、聚合等,是数据预处理和分析的基石。
接下来,我们就一步步揭开 DataFrame 的面纱,从创建到操作,再到实战应用。
创建 DataFrame 的多种方式
DataFrame 可以通过多种方式创建,最常见的是从字典、列表、NumPy 数组,甚至是文件中读取数据。
从字典创建
字典的键作为列名,值作为列的数据。这是最直观的方式之一。
import pandas as pd
data = {
'姓名': ['张三', '李四', '王五', '赵六'],
'年龄': [20, 22, 19, 21],
'成绩': [88.5, 92.0, 76.5, 85.0],
'是否及格': [True, True, False, True]
}
df = pd.DataFrame(data)
print(df.head())
注释:这段代码将一个 Python 字典转换为一个 DataFrame。键 '姓名'、'年龄' 等成为列名,对应的列表成为列数据。
head()方法显示前 5 行,用于快速预览数据。
从列表创建
如果数据是嵌套列表,每一行代表一条记录。
student_list = [
['张三', 20, 88.5, True],
['李四', 22, 92.0, True],
['王五', 19, 76.5, False],
['赵六', 21, 85.0, True]
]
df2 = pd.DataFrame(student_list, columns=['姓名', '年龄', '成绩', '是否及格'])
print(df2)
注释:这里我们用
columns参数显式指定列名。如果省略,Pandas 会默认使用 0, 1, 2, 3 作为列名,这显然不直观。因此,建议总是指定列名。
从 NumPy 数组创建
当数据来自科学计算或机器学习项目时,常使用 NumPy 数组。Pandas 可以轻松将它们转换为 DataFrame。
import numpy as np
arr = np.random.randn(4, 4)
df3 = pd.DataFrame(arr, columns=['A', 'B', 'C', 'D'], index=['X', 'Y', 'Z', 'W'])
print(df3)
注释:
index参数用于设置行标签(行名),columns用于设置列名。这使得 DataFrame 不仅有数据,还有清晰的结构标签。
DataFrame 的核心特性解析
DataFrame 之所以强大,是因为它具备多个核心特性,这些特性让它在处理真实世界数据时游刃有余。
行与列的标签化设计
与普通的数组不同,DataFrame 的行和列都有名称。这种标签化设计让你能用“名字”来操作数据,而不是记住位置。
print("列名:", df.columns)
print("行索引:", df.index)
df.rename(columns={'成绩': '分数'}, inplace=True)
df.index = ['学生1', '学生2', '学生3', '学生4']
注释:
inplace=True表示直接修改原对象,不返回新对象。rename方法可用于修改列或行标签,让数据更具可读性。
支持异构数据类型
一个 DataFrame 的不同列可以是不同的数据类型。比如一列是整数(年龄),一列是浮点数(成绩),一列是布尔值(是否及格),甚至可以是字符串。
print(df.dtypes)
输出示例:
姓名 object 年龄 int64 分数 float64 是否及格 bool dtype: object
注释:
dtypes属性显示每列的数据类型。object通常表示字符串,int64是整数,float64是浮点数,bool是布尔值。这种灵活性让 DataFrame 能处理真实世界中混杂的数据。
灵活的索引机制
DataFrame 支持两种索引方式:位置索引(基于整数)和标签索引(基于名称)。
print(df.iloc[0]) # 第 1 行(索引 0)
print(df.iloc[0:2]) # 第 1~2 行(索引 0 和 1)
print(df.loc['学生1']) # 查找行标签为 '学生1' 的行
print(df.loc['学生1':'学生3']) # 查找从 '学生1' 到 '学生3' 的行
注释:
iloc用于基于整数位置的索引,loc用于基于标签的索引。使用loc时,如果行标签不存在,会抛出 KeyError;而iloc只要位置合法即可访问。
数据操作实战:筛选、排序与修改
掌握 DataFrame 的创建后,接下来就是如何操作数据。这是数据分析的核心环节。
条件筛选
你可以用布尔表达式筛选出满足特定条件的行。
high_scorers = df[df['分数'] > 85]
print(high_scorers)
filtered = df[(df['分数'] > 85) & (df['是否及格'] == True)]
print(filtered)
注释:布尔筛选非常强大。注意多条件必须用括号包裹,并且使用
&(与)、|(或)、~(非)而不是and、or、not。这是因为 Pandas 重载了这些操作符以支持向量化运算。
排序
对数据进行排序是常见需求。DataFrame 支持按列排序。
sorted_df = df.sort_values(by='分数', ascending=False)
print(sorted_df)
sorted_df = df.sort_values(by=['年龄', '分数'], ascending=[True, False])
print(sorted_df)
注释:
by参数指定排序依据的列,ascending控制升序或降序。多级排序时,会先按第一个列排序,再按第二个列进行次级排序。
数据修改与新增列
你可以在 DataFrame 中添加新列,或修改已有列。
def get_grade(score):
if score >= 90:
return 'A'
elif score >= 80:
return 'B'
elif score >= 70:
return 'C'
else:
return 'D'
df['等级'] = df['分数'].apply(get_grade)
print(df)
注释:
apply()方法对某一列的每个元素应用函数。这里我们自定义了一个get_grade函数,根据分数返回等级,并将其添加为新列。这是数据清洗和特征工程的典型操作。
DataFrame 的常用统计与聚合方法
在分析数据时,我们常常需要计算总和、平均值、最大值等统计量。
print(df.describe())
avg_age = df['年龄'].mean()
print(f"平均年龄:{avg_age:.2f}")
max_score = df['分数'].max()
print(f"最高分:{max_score}")
grouped = df.groupby('是否及格')['分数'].mean()
print(grouped)
注释:
describe()提供计数、均值、标准差、最小值、四分位数、最大值等统计信息。groupby()是强大的分组操作,常用于按类别分析数据。
| 是否及格 | 平均分数 |
|---|---|
| False | 76.50 |
| True | 88.50 |
注释:
groupby会按“是否及格”分组,然后对每组的“分数”列计算均值,结果是一个新的 Series,清晰展示出及格与不及格学生的平均表现差异。
实战案例:处理真实数据文件
让我们模拟一个真实场景:读取一个 CSV 文件,进行清洗和分析。
df_sales = pd.read_csv('sales_data.csv')
print(df_sales.head())
print("缺失值统计:")
print(df_sales.isnull().sum())
df_sales['销售额'].fillna(df_sales['销售额'].mean(), inplace=True)
df_sales['利润率'] = df_sales['利润'] / df_sales['销售额']
total_sales_by_region = df_sales.groupby('地区')['销售额'].sum()
print(total_sales_by_region)
注释:
read_csv()是读取文件的核心方法。isnull().sum()统计每列缺失值数量。fillna()用于填充缺失值。groupby与聚合结合,可快速生成关键业务指标。
总结
Pandas 数据结构 – DataFrame 是现代数据分析的基石。它不仅具备表格的直观结构,还融合了强大的编程能力,让你能用代码完成从数据加载、清洗、筛选、排序到聚合分析的全流程。
从创建、查看、修改到复杂操作,DataFrame 提供了一整套完整的工具链。无论是初学者还是中级开发者,只要掌握其核心概念和常用方法,就能高效处理各种数据任务。
记住:数据的价值不在于它有多大,而在于你能否从中提取出有意义的信息。而 DataFrame,正是你通往数据洞察的第一步。