Pandas:数据处理与分析
AI 项目 80% 的时间花在数据处理上。Pandas 是处理表格数据的利器,从数据清洗到特征工程,它是 AI 数据管道的核心工具。
Pandas 核心术语
- DataFrame Pandas 最核心的数据结构,本质是二维标记数据表,行有索引,列有名称,不同列可以有不同数据类型。类比 Excel 工作表或 SQL 数据库的表。
- Series 一维带索引的数据结构,DataFrame 的一列就是一个 Series。Series 保留索引,可以方便地按标签对齐数据。
- 索引(Index) DataFrame 的行标签,默认是 0、1、2... 的整数,也可以是字符串、时间戳等。好的索引设计让数据检索更高效,如以用户ID为索引的用户行为数据。
- 缺失值(NaN) Not a Number,Pandas 用来表示缺失数据的特殊浮点值。真实数据几乎总有缺失值,处理方式包括删除(dropna)、填充均值/众数/前向值(fillna)或插值。
-
向量化操作(Vectorized Operations)
Pandas 运算都是向量化的,作用于整列数据。
df["age"] * 2会将整列乘以2,比 Python for 循环快得多。应该避免使用iterrows()逐行处理大数据集。 - 特征工程(Feature Engineering) 将原始数据转换为机器学习模型能更好利用的特征。包括归一化、类别编码、创建交叉特征、时间特征提取等。好的特征工程往往比换算法更有效。
DataFrame —— 表格数据的核心
Pandas 最重要的结构是 DataFrame,本质上是一张带有行索引和列标签的二维表格,就像 Excel 表格,但能处理百万级数据且可编程。每一列是一个 Series。
DataFrame vs NumPy 数组
NumPy 数组的列是匿名的数字索引,所有数据必须同类型。DataFrame 的列有名字,不同列可以有不同类型(年龄是 int,姓名是 str,分数是 float)。这让它非常适合处理真实的 AI 训练数据集。
import pandas as pd
import numpy as np
# 从字典创建(最常用)
df = pd.DataFrame({
"样本ID": ["s001", "s002", "s003", "s004"],
"年龄": [25, 30, None, 22], # None = 缺失值
"收入": [5000, 8000, 6000, 4500],
"标签": [1, 0, 1, 0],
})
# 查看基本信息
print(df) # 打印整张表
print(df.shape) # (4, 4) → 4行4列
print(df.dtypes) # 各列的数据类型
print(df.info()) # 完整信息,含非空值数量
print(df.describe()) # 数值列的统计摘要(均值、标准差等)
# 从 CSV 读取(实际项目最常见)
df = pd.read_csv("train_data.csv")
df.to_csv("output.csv", index=False) # 保存,不写行号
# 前/后几行预览
print(df.head(5)) # 前5行
print(df.tail(3)) # 后3行
print(df.sample(3)) # 随机3行
选取数据:loc 和 iloc
Pandas 有两种主要的数据选取方式:loc 按标签选取,iloc 按整数位置选取。分清这两者,是使用 Pandas 的关键。
df = pd.DataFrame({
"feature1": [0.1, 0.5, 0.3, 0.8],
"feature2": [1.2, 2.3, 0.9, 3.1],
"label": [0, 1, 0, 1]
})
# 选取列(单列返回 Series,多列返回 DataFrame)
labels = df["label"] # Series
features = df[["feature1", "feature2"]] # DataFrame
# loc:按标签选取行列
print(df.loc[0]) # 第0行(行索引是整数时)
print(df.loc[0:2]) # 第0-2行(包含第2行!)
print(df.loc[0, "feature1"]) # 第0行 feature1 列
# iloc:按整数位置选取
print(df.iloc[0]) # 第0行
print(df.iloc[:2, :2]) # 前2行前2列
print(df.iloc[-1]) # 最后一行
# 条件筛选(最常用!)
positive = df[df["label"] == 1] # 所有正样本
high_feat = df[df["feature2"] > 2.0] # feature2 > 2 的行
multi = df[(df["label"]==1) & (df["feature1"]>0.4)]
print(positive)
数据清洗
真实数据总是"脏的"——有缺失值、重复行、异常值。在送入模型前必须清洗,否则会严重影响训练效果。"垃圾进,垃圾出(Garbage In, Garbage Out)"是 AI 领域的著名定律。
# 检查缺失值
print(df.isnull().sum()) # 每列缺失值数量
print(df.isnull().sum() / len(df)) # 缺失比例
# 处理缺失值
df_drop = df.dropna() # 删除含缺失值的行
df_fill = df.fillna(0) # 用0填充所有缺失值
# 按列填充(更好的做法)
df["年龄"] = df["年龄"].fillna(df["年龄"].mean()) # 用均值填充
df["类别"] = df["类别"].fillna(df["类别"].mode()[0]) # 用众数填充
df["值"] = df["值"].fillna(method="ffill") # 前向填充
# 删除重复行
df = df.drop_duplicates()
df = df.drop_duplicates(subset=["样本ID"]) # 按指定列去重
# 处理异常值(基于 3σ 原则)
col = "收入"
mean, std = df[col].mean(), df[col].std()
df = df[(df[col] >= mean - 3 * std) &
(df[col] <= mean + 3 * std)]
# 重置行索引
df = df.reset_index(drop=True)
特征工程
特征工程是将原始数据转换为模型能更好学习的格式。好的特征工程常常比换一个更复杂的模型效果更显著。
# 1. 数值归一化(Min-Max Scaling)
for col in ["年龄", "收入"]:
min_v = df[col].min()
max_v = df[col].max()
df[col] = (df[col] - min_v) / (max_v - min_v)
# 2. 类别编码(One-Hot Encoding)
df = pd.get_dummies(df, columns=["城市"], prefix="city")
# "北京", "上海", "广州" → city_北京, city_上海, city_广州(0或1)
# 3. 标签编码(Label Encoding)
df["性别_num"] = df["性别"].map({"男": 0, "女": 1})
# 4. 创建新特征(组合特征)
df["收入/年龄"] = df["收入"] / df["年龄"]
df["高收入"] = (df["收入"] > 0.7).astype(int)
# 5. 时间特征提取
df["日期"] = pd.to_datetime(df["日期"])
df["月份"] = df["日期"].dt.month
df["星期"] = df["日期"].dt.dayofweek
df["是否周末"] = (df["星期"] >= 5).astype(int)
特征工程的黄金法则
神经网络理论上能自动学习特征,但提供好的特征仍然有帮助。对于结构化数据(表格),特征工程是关键。对于图像和文本,通常让模型自己学。pd.get_dummies() 是处理类别变量最常用的方法,面试必考。
groupby —— 分组聚合
groupby 是 Pandas 最强大的功能之一,类似 SQL 的 GROUP BY:按某列分组,再对每组做统计。在 AI 中用于按类别分析数据分布是否均衡。
df = pd.DataFrame({
"类别": ["猫", "狗", "猫", "狗", "鸟", "鸟"],
"得分": [0.8, 0.6, 0.9, 0.7, 0.5, 0.55],
"置信度": [0.9, 0.7, 0.85, 0.75, 0.6, 0.65],
})
# 按类别分组,计算各列均值
print(df.groupby("类别").mean())
# 多种聚合函数同时计算
summary = df.groupby("类别")["得分"].agg(["mean", "std", "count"])
print(summary)
# 查看类别分布(AI 中用于检查数据是否均衡)
print(df["类别"].value_counts())
print(df["类别"].value_counts(normalize=True)) # 百分比
# 相关性分析(特征选择)
print(df.corr()) # 各数值列之间的相关系数矩阵
综合示例:完整数据预处理流程
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
# 1. 加载数据
df = pd.read_csv("titanic.csv")
print(f"原始数据: {df.shape}")
# 2. 查看缺失情况
print(df.isnull().sum())
# 3. 清洗
df["Age"] = df["Age"].fillna(df["Age"].median())
df["Embarked"] = df["Embarked"].fillna(df["Embarked"].mode()[0])
df = df.drop(columns=["Cabin", "Ticket", "Name", "PassengerId"])
# 4. 特征工程
df["Sex"] = df["Sex"].map({"male": 0, "female": 1})
df = pd.get_dummies(df, columns=["Embarked"])
df["FamilySize"] = df["SibSp"] + df["Parch"] + 1
# 5. 分离特征和标签
X = df.drop(columns=["Survived"])
y = df["Survived"]
# 6. 切分训练集测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
print(f"训练集: {X_train.shape}, 测试集: {X_test.shape}")
print(f"正负样本比: {y_train.mean():.2%}")
这是 Kaggle 竞赛的标准流程
上面的泰坦尼克号数据集是机器学习入门的"Hello World"。这个预处理流程——读取→清洗→特征工程→切分——在几乎所有结构化数据的 AI 项目中都适用。
常见误区与性能陷阱
SettingWithCopyWarning:视图修改陷阱
Pandas 中 df[df["col"] > 0]["new_col"] = 1 可能修改的是视图而非原 DataFrame,会触发 SettingWithCopyWarning 且不生效。正确做法:用 .loc 明确定位:df.loc[df["col"] > 0, "new_col"] = 1。这是初学者最常踩的 Pandas 坑。
loc vs iloc 的 slice 行为不同
df.loc[0:3] 包含第 3 行(标签 3),df.iloc[0:3] 不包含第 3 行(位置 3)。loc 是标签切片(包含终点),iloc 是位置切片(不含终点)。混淆这两者会导致 off-by-one 错误,在数据集切分时会漏掉或多取样本。
避免 iterrows() 遍历大 DataFrame
for idx, row in df.iterrows() 逐行处理数百万行数据极慢(Python 层面的循环)。应该使用向量化操作(df["col"].apply(func))或 df.assign()。性能关键路径上可用 NumPy 数组直接操作:df["col"].values 提取为 ndarray。
import pandas as pd
# 1. method chaining(链式调用)—— 更Pythonic
result = (
pd.read_csv("data.csv")
.dropna(subset=["label"]) # 删除缺失标签的行
.rename(columns={"user_id": "id"}) # 重命名列
.query("age >= 18") # 筛选成年用户
.reset_index(drop=True) # 重置索引
)
# 2. pd.cut / pd.qcut:数值分箱(特征工程常用)
df = pd.DataFrame({"score": [35, 55, 72, 88, 95]})
df["level"] = pd.cut(
df["score"],
bins=[0, 60, 80, 100],
labels=["低", "中", "高"]
)
print(df)
# 3. 透视表(分析类别×类别的交叉统计)
pivot = df.pivot_table(
values="score",
index="level",
aggfunc=["mean", "count"]
)
print(pivot)
本章小结
Pandas 是 AI 数据预处理的核心工具。DataFrame 是带标签的二维表格,Series 是一列。关键操作:loc(标签索引)、iloc(位置索引)、条件筛选、dropna/fillna(缺失值处理)、groupby(分组聚合)。特征工程步骤:归一化 → 类别编码 → 创建新特征 → 切分数据集。三个重要陷阱:SettingWithCopyWarning(用 .loc 避免)、loc 包含终点而 iloc 不包含、避免 iterrows() 逐行处理大数据。AI 项目 80% 的时间花在数据处理上,熟练掌握 Pandas 是提高效率的关键。