在机器学习项目中,数据决定模型上限,而 Pandas 作为 Python 数据分析的核心库,正是打通 “原始数据” 到 “可用特征” 的关键工具。无论是数据清洗、探索性分析,还是特征提取与转换,Pandas 都能以简洁的代码高效完成。本文将结合机器学习真实场景,从基础操作到进阶技巧,带你掌握 Pandas 在机器学习中的核心应用。

一、Pandas 与机器学习:为什么它是 “第一块拼图”?

在机器学习流水线(Data Pipeline)中,Pandas 主要承担数据准备阶段的工作,对应整个项目 60%-80% 的时间占比。其核心价值体现在:

  • 结构化数据处理:轻松应对 CSV、Excel、SQL 等常见数据格式,兼容机器学习中最常用的表格型数据;
  • 灵活的数据清洗:快速处理缺失值、异常值、重复值,解决 “脏数据” 无法直接输入模型的问题;
  • 高效特征工程:支持数值型、分类型、时间型特征的加工,为模型提供高质量输入;
  • 无缝衔接其他库:与 NumPy(数值计算)、Matplotlib/Seaborn(可视化)、Scikit-learn(建模)完美兼容,形成 “数据 - 分析 - 建模” 闭环。

先安装并导入 Pandas(通常搭配 NumPy 使用):

# 安装命令
# pip install pandas numpy

# 导入库
import pandas as pd
import numpy as np

二、基础操作:机器学习中的 “数据读写与查看”

机器学习的第一步,是加载数据并快速了解数据全貌。Pandas 提供了直观的 API 完成这一环节。

1. 读取常见数据格式

机器学习中最常用的是 CSV 格式数据,此外 Excel、SQL 数据也可通过 Pandas 直接读取:

# 1. 读取 CSV 文件(最常用)
df = pd.read_csv("machine_learning_data.csv")  # 本地文件
# df = pd.read_csv("https://xxx.com/data.csv")  # 远程文件

# 2. 读取 Excel 文件(需安装 openpyxl)
# df = pd.read_excel("data.xlsx", sheet_name="Sheet1")

# 3. 读取 SQL 数据(需搭配 SQLAlchemy)
# from sqlalchemy import create_engine
# engine = create_engine("mysql+pymysql://user:password@host/db")
# df = pd.read_sql("SELECT * FROM table", engine)

2. 快速探索数据:3 行代码掌握核心信息

拿到数据后,无需逐行查看,用以下代码快速判断数据是否 “可用”:

# 1. 查看前5行数据(了解字段含义和数据格式)
print(df.head())

# 2. 查看数据基本信息(行数、列数、数据类型、缺失值)
print(df.info())
# 输出示例:
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 1000 entries, 0 to 999  # 1000行数据
# Data columns (total 5 columns):
#  #   Column    Non-Null Count  Dtype  
# ---  ------    --------------  -----  
#  0   age       950 non-null    float64  # 50个缺失值
#  1   gender    1000 non-null   object   # 分类型数据
#  2   income    1000 non-null   int64    # 数值型数据
#  3   purchase  1000 non-null   int64    # 目标变量(是否购买)
#  4   date      1000 non-null   object   # 时间型数据(需转换)

# 3. 查看数值型特征的统计描述(判断异常值)
print(df.describe())
# 输出均值、标准差、最值、四分位数,可快速发现异常(如age=1000明显不合理)

三、核心应用 1:数据清洗 —— 解决机器学习的 “数据痛点”

原始数据往往存在缺失值、异常值、重复值,这些问题会直接导致模型训练失败或效果偏差。Pandas 提供了高效的清洗方案。

1. 处理缺失值:两种核心策略

缺失值是机器学习中最常见的问题,Pandas 支持 “填充” 和 “删除” 两种主流处理方式,需根据特征重要性选择:

# 1. 查看各字段缺失值比例(先定位问题)
missing_ratio = df.isnull().sum() / len(df) * 100
print(missing_ratio)
# 输出示例:age:5.0%, gender:0.0%, income:0.0%, purchase:0.0%, date:0.0%

# 2. 策略1:删除缺失值(缺失比例低且特征不重要时)
df_clean1 = df.dropna(subset=["age"])  # 仅删除age列有缺失的行
# df_clean1 = df.dropna(thresh=4)  # 保留至少4个非空值的行

# 3. 策略2:填充缺失值(特征重要时,避免数据损失)
# 数值型特征:用均值/中位数填充(中位数更抗异常值)
df["age"] = df["age"].fillna(df["age"].median())  # 用中位数填充age缺失值
# 分类型特征:用众数填充
df["gender"] = df["gender"].fillna(df["gender"].mode()[0])  # mode()返回Series,取第一个众数

2. 处理异常值:识别并修正 “不合理数据”

异常值(如年龄 = 200、收入 =-1000)会严重干扰模型,需先识别再处理:

# 1. 用“箱线图”可视化异常值(直观)
import seaborn as sns
import matplotlib.pyplot as plt
sns.boxplot(x=df["income"])
plt.show()  # 超出上下四分位数1.5倍范围的为异常值

# 2. 用代码识别异常值(基于IQR方法)
Q1 = df["income"].quantile(0.25)  # 下四分位数
Q3 = df["income"].quantile(0.75)  # 上四分位数
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR  # 下界
upper_bound = Q3 + 1.5 * IQR  # 上界

# 3. 处理异常值:两种方式
# 方式1:删除异常值(异常数据少且确认错误时)
df_clean = df[(df["income"] >= lower_bound) & (df["income"] <= upper_bound)]
# 方式2:修正为边界值(异常数据多,避免删除过多样本)
df["income"] = np.where(df["income"] < lower_bound, lower_bound, df["income"])
df["income"] = np.where(df["income"] > upper_bound, upper_bound, df["income"])

3. 处理重复值:避免 “数据偏见”

重复行会导致模型过度学习重复样本,需删除:

# 1. 查看重复行数量
print(f"重复行数量:{df.duplicated().sum()}")  # 输出重复行的个数

# 2. 删除重复行(保留第一行)
df = df.drop_duplicates(keep="first")

四、核心应用 2:特征工程 —— 为模型 “喂好料”

特征工程是机器学习的 “灵魂”,Pandas 可高效完成数值型、分类型、时间型特征的加工,让模型更易学习数据规律。

1. 分类型特征:编码为 “模型可识别的数值”

机器学习模型无法直接处理字符串(如 “男 / 女”“北京 / 上海”),需将其转换为数值,常用两种编码方式:

编码方式适用场景Pandas 实现
标签编码(Label Encoding)有序分类(如 “低 / 中 / 高”)df["grade"] = df["grade"].map({"低":0, "中":1, "高":2})
独热编码(One-Hot Encoding)无序分类(如 “性别”“城市”)pd.get_dummies(df, columns=["gender", "city"], drop_first=True)

实战代码

# 1. 标签编码:处理有序分类(如教育程度)
df["education"] = df["education"].map({"小学":0, "初中":1, "高中":2, "大学及以上":3})

# 2. 独热编码:处理无序分类(如性别、城市)
# drop_first=True:避免多重共线性(如“男=0”可代表“女=1”)
df_onehot = pd.get_dummies(
    df, 
    columns=["gender", "city"],  # 需要编码的列
    drop_first=True  # 删除第一个类别,减少特征数量
)
print(df_onehot.columns)  # 新增“gender_男”“city_上海”等列

2. 数值型特征:优化与衍生

对数值型特征(如年龄、收入)进行加工,可增强模型对数据的理解:

# 1. 特征归一化/标准化(消除量纲影响,适用于逻辑回归、SVM等模型)
# 归一化(缩放到[0,1])
df["income_normalized"] = (df["income"] - df["income"].min()) / (df["income"].max() - df["income"].min())
# 标准化(均值=0,标准差=1)
df["age_standardized"] = (df["age"] - df["age"].mean()) / df["age"].std()

# 2. 衍生新特征(基于业务逻辑)
# 示例:计算“收入/年龄”比率(反映单位年龄的收入水平)
df["income_per_age"] = df["income"] / df["age"]
# 示例:将年龄分箱(把连续值转为分类,捕捉非线性关系)
df["age_group"] = pd.cut(
    df["age"], 
    bins=[0, 20, 30, 40, 100],  # 分箱边界
    labels=["<20", "20-30", "30-40", ">40"]  # 类别标签
)

3. 时间型特征:提取 “时间维度信息”

如果数据包含时间字段(如 “购买日期”),可提取年、月、周等信息,捕捉时间规律:

# 1. 先将字符串转换为时间格式
df["date"] = pd.to_datetime(df["date"])  # 自动识别时间格式

# 2. 提取时间特征
df["year"] = df["date"].dt.year  # 年份(如2023)
df["month"] = df["date"].dt.month  # 月份(1-12)
df["day"] = df["date"].dt.day  # 日期(1-31)
df["is_weekend"] = df["date"].dt.weekday >= 5  # 是否周末(5=周六,6=周日)
df["is_weekend"] = df["is_weekend"].astype(int)  # 转为0/1

# 3. 计算时间差(如“距离今天的天数”)
today = pd.Timestamp("2024-01-01")
df["days_since_today"] = (today - df["date"]).dt.days

五、核心应用 3:数据拆分 —— 衔接模型训练

完成数据清洗和特征工程后,需用 Pandas 拆分特征(X)和目标变量(y) ,再划分训练集和测试集(通常用 Scikit-learn 配合)。

# 1. 拆分特征(X)和目标变量(y)
# 假设“purchase”是目标变量(1=购买,0=不购买),其他列是特征
X = df.drop(columns=["purchase", "date"])  # 删除目标变量和无用列
y = df["purchase"]  # 目标变量

# 2. 划分训练集和测试集(用Scikit-learn,需先安装)
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
    X, y, 
    test_size=0.2,  # 测试集占比20%
    random_state=42,  # 固定随机种子,确保结果可复现
    stratify=y  # 分层抽样,保证训练集和测试集目标变量分布一致
)

print(f"训练集特征形状:{X_train.shape}")  # 输出:(800, 10) (800行,10个特征)
print(f"测试集特征形状:{X_test.shape}")    # 输出:(200, 10)

六、实战案例:用 Pandas 完成 “用户购买预测” 数据准备

结合上述所有步骤,我们用一个完整案例演示 Pandas 在机器学习中的全流程应用:

# 1. 加载数据
df = pd.read_csv("user_purchase_data.csv")

# 2. 数据探索
print("数据基本信息:")
print(df.info())
print("\n缺失值比例:")
print(df.isnull().sum() / len(df) * 100)

# 3. 数据清洗
# 填充缺失值
df["age"] = df["age"].fillna(df["age"].median())
# 处理异常值(年龄>100视为异常)
df = df[df["age"] <= 100]
# 删除重复行
df = df.drop_duplicates()

# 4. 特征工程
# 分类型特征编码
df["gender"] = df["gender"].map({"女":0, "男":1})  # 标签编码
df = pd.get_dummies(df, columns=["city"], drop_first=True)  # 独热编码
# 时间特征提取
df["purchase_date"] = pd.to_datetime(df["purchase_date"])
df["month"] = df["purchase_date"].dt.month
df["is_weekend"] = (df["purchase_date"].dt.weekday >= 5).astype(int)
# 衍生数值特征
df["income_per_age"] = df["income"] / df["age"]

# 5. 拆分数据
X = df.drop(columns=["purchase", "purchase_date"])
y = df["purchase"]
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

print(f"\n数据准备完成!训练集:{X_train.shape},测试集:{X_test.shape}")

七、Pandas 机器学习避坑指南

  1. 避免修改原始数据:建议用 df.copy() 创建副本后操作,防止原始数据被污染;
  2. 注意数据类型:用 df.dtypes 检查数据类型,确保 “数值型特征为 float/int,时间型为 datetime”;
  3. 独热编码后特征名变化:编码后特征名会新增(如 “city_上海”),后续引用需注意;
  4. 缺失值填充需区分类型:数值型用均值 / 中位数,分类型用众数,不要混用;
  5. 大规模数据优化:处理百万级数据时,用 df.itertuples() 代替 df.iterrows(),用 pd.concat() 代替 df.append()(效率更高)。

八、总结

在机器学习中,Pandas 不仅是 “数据处理工具”,更是连接 “原始数据” 与 “高质量模型” 的桥梁。从数据加载、清洗到特征工程,Pandas 以简洁的 API 降低了数据分析的门槛,让开发者能更专注于模型优化和业务逻辑。

掌握 Pandas 不是终点,而是机器学习的起点 —— 当你能用 Pandas 快速解决数据问题时,才能更高效地验证业务想法、迭代模型效果。建议结合真实数据集多练手(如 Kaggle 上的 Titanic、House Price 数据集),逐步形成自己的 “数据处理方法论”!

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐