大家好!今天咱们用超通俗的语言,手把手拆解一段矿物数据预处理的代码。哪怕你刚接触 Python、没碰过数据分析,也能看懂每一步在干啥。

预处理是数据分析 / 机器学习的第一步,也是最关键的一步 —— 就像做饭要先洗菜切菜,数据得先 “收拾干净” 才能用。这段代码的核心目标是:把一份杂乱的矿物数据,整理成能直接喂给机器学习模型的训练集和测试集。

先看整体流程

先给大家画个 “路线图”,知道咱们要做哪些事:

  1. 导入工具包 → 2. 读取数据 → 3. 清理异常数据 → 4. 处理缺失值 → 5. 标签编码 → 6. 数据标准化 → 7. 划分训练 / 测试集 → 8. 解决样本不均衡 → 9. 保存处理好的数据

代码逐行解析(小白友好版)

第一步:导入需要的 “工具包”

python

运行

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np  # 补充numpy,用于缺失值处理
import fill_data  # 自定义的填充缺失值的工具包(自己写的py文件)
  • pandas (pd):专门用来处理表格数据(比如 Excel),新手记死:读 Excel、改数据都靠它。
  • matplotlib.pyplot (plt):画图用的(这段代码没用到,但导入了备用)。
  • numpy (np):数值计算工具,处理缺失值、数组运算都需要。
  • fill_data:这是自定义的 py 文件(需要你自己创建),里面写了填充缺失值的函数(比如平均值填充、众数填充)。

第二步:读取矿物数据文件

python

运行

# 读取矿物数据
data = pd.read_excel("矿物数据.xls")
  • pd.read_excel():pandas 读取 Excel 文件的函数,括号里填文件路径。
  • 注意:如果文件和代码不在同一个文件夹,要写完整路径(比如"C:/桌面/矿物数据.xls")。
  • 执行后,data就是一个 “表格”(DataFrame),和 Excel 里的样子几乎一样。

第三步:删除异常的矿物类型

python

运行

# 删除特殊的类别E(整个数据集中只存在1个E数据)
data = data[data['矿物类型'] != 'E']
  • 解释:数据里有个 “矿物类型” 列,其中只有 1 个 “E” 类型的数据,样本太少没意义,直接删掉。
  • data['矿物类型'] != 'E':筛选出 “矿物类型” 不是 E 的所有行。
  • 新手类比:就像从 Excel 里筛选掉 “E” 类型的行,只保留 A/B/C/D。

第四步:检测缺失值(看看哪些格子是空的)

python

运行

# 检测缺失值
null_num = data.isnull()
null_total = null_num.sum()  # 检测每列中的缺失值
  • data.isnull():遍历表格每个格子,空值标True,非空标False
  • null_num.sum():按列统计True的数量(也就是每列有多少个空值)。
  • 作用:让你知道数据 “缺了多少”,比如某列有 50 个空值,后续要处理。

第五步:分离特征和标签(机器学习必备)

python

运行

# 获取全部特征数据和标签数据
X_whole = data.drop('矿物类型', axis=1).drop('序号', axis=1)
y_whole = data.矿物类型
  • 机器学习里,数据分两类:
    • 特征(X):用来 “预测” 的依据(比如矿物的硬度、密度、成分等);
    • 标签(y):要预测的目标(这里就是 “矿物类型”)。
  • data.drop('矿物类型', axis=1):删掉 “矿物类型” 列(axis=1 表示删列),剩下的都是特征;
  • .drop('序号', axis=1):删掉 “序号” 列(序号只是编号,不是特征);
  • y_whole = data.矿物类型:单独把 “矿物类型” 列拿出来当标签。

第六步:把中文标签转成数字(机器只认数字)

python

运行

# 将数据中的中文标签转换为数字编码
label_dict = {"A": 0, "B": 1, "C": 2, "D": 3}
encoded_labels = [label_dict[label] for label in y_whole]
y_whole = pd.Series(encoded_labels, name='矿物类型')
  • 解释:机器学习模型不认识 “A/B/C/D”,必须转成数字(0/1/2/3)。
  • label_dict:字典,相当于 “翻译手册”,A→0、B→1…
  • [label_dict[label] for label in y_whole]:遍历所有标签,按手册翻译成数字(列表推导式,新手不用深究,知道是 “批量翻译” 就行);
  • pd.Series():把翻译后的数字列表转回 pandas 的列,保持格式统一。

第七步:清理异常数值(把乱码转成可计算的格式)

python

运行

# 数据中存在大量字符串数值、\、空格等异常数据。字符串数值直接转换为float,\和空格转换为nan
for column_name in X_whole.columns:
    X_whole[column_name] = pd.to_numeric(X_whole[column_name], errors='coerce')
  • 问题:原始数据里可能有这些 “脏数据”:比如把数字写成字符串(“123”)、有斜杠(/)、空格( ),这些都没法计算。
  • 解决:
    • for column_name in X_whole.columns:遍历每一列特征;
    • pd.to_numeric(..., errors='coerce'):把列里的内容转成数字:
      • 能转的(比如 “123”)→ 转成 float(小数);
      • 不能转的(比如 /、空格)→ 转成nan(缺失值,后续统一填充)。

第八步:数据标准化(让特征 “站在同一起跑线”)

python

运行

"""数据标准化:Z标准化,0~1标准化"""
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
X_whole_Z = scaler.fit_transform(X_whole)
X_whole = pd.DataFrame(X_whole_Z, columns=X_whole.columns)  # Z标准化处理后为numpy数据,这里再转换回pandas数据
  • 为什么要标准化?比如特征里有 “硬度(1-10)” 和 “密度(1000-5000)”,密度的数值太大,会 “盖过” 硬度的影响,模型会跑偏。
  • StandardScaler():Z 标准化工具,把每个特征转成 “均值为 0,标准差为 1” 的数(不用记公式,知道作用就行);
  • scaler.fit_transform(X_whole):对所有特征做标准化;
  • 最后转回 DataFrame:标准化后是数组(numpy),转成表格方便后续处理。

第九步:划分训练集和测试集(模型训练的规矩)

python

运行

'''数据集的切分'''
from sklearn.model_selection import train_test_split
x_train_w, x_test_w, y_train_w, y_test_w = \
    train_test_split(X_whole, y_whole, test_size=0.3, random_state=50000)
  • 解释:把数据分成两部分:
    • 训练集(70%):用来教模型 “认矿物”;
    • 测试集(30%):用来检验模型学得好不好。
  • train_test_split():专门划分数据的函数;
    • test_size=0.3:测试集占 30%;
    • random_state=50000:固定随机种子(保证每次划分结果一样,新手照抄就行);
  • 输出:x_train_w(训练特征)、x_test_w(测试特征)、y_train_w(训练标签)、y_test_w(测试标签)。

第十步:填充缺失值(把空值补上)

python

运行

'''数据中存在空缺,进行6种方法进行填充'''
# # # 1、只保留完整行的数据集
# x_train_fill, y_train_fill = fill_data.cca_train_fill(x_train_w, y_train_w)  # 调用自己写的implement_data.py文件中的
# # # 测试集的填充
# x_test_fill, y_test_fill = fill_data.cca_test_fill(x_train_fill, y_train_fill, x_test_w, y_test_w)  # 调用自己写

#2、使用平均值的方法对数据进行填充
x_train_fill, y_train_fill = fill_data.mean_train_fill(x_train_w, y_train_w)
# 测试集的填充
x_test_fill, y_test_fill = fill_data.mean_test_fill(x_train_fill, y_train_fill, x_test_w, y_test_w)
#
# #2、使用众数的方法对数据进行填充
# x_train_fill, y_train_fill = fill_data.mean_train_fill(x_train_w, y_train_w)
# # 测试集的填充
# x_test_fill, y_test_fill = fill_data.mean_test_fill(x_train_fill, y_train_fill, x_test_w, y_test_w)
  • 问题:前面把异常数据转成了nan(空值),空值不能喂给模型,必须补上;
  • 方法 1(注释掉):cca_train_fill → 只保留没有空值的行(简单但会丢数据);
  • 方法 2(在用):mean_train_fill → 用每列的平均值填充空值(最常用的方法);
  • 注意:
    • 训练集和测试集要分开填充!测试集必须用训练集的平均值(避免 “数据泄露”);
    • fill_data.mean_train_fill():调用自定义文件里的平均值填充函数(新手可以先理解逻辑,函数实现文末附)。

第十一步:解决样本不均衡(让模型不 “偏心”)

python

运行

'''smote算法实现数据集的拟合,解决样本不均衡'''
from imblearn.over_sampling import SMOTE

oversampler = SMOTE(k_neighbors=1, random_state=42)  # 数据对象
os_x_train, os_y_train = oversampler.fit_resample(x_train_fill, y_train_fill)  # 人工拟合的只是训练集
  • 什么是样本不均衡?比如 A 类型矿物有 1000 个样本,B 类型只有 10 个,模型会 “偏爱” A,预测 B 时准确率极低;
  • SMOTE:超实用的算法,能 “人工生成” 少数类的样本(比如给 B 类型造 990 个相似样本),让各类样本数量差不多;
  • k_neighbors=1:生成样本时参考最近的 1 个样本(新手照抄);
  • fit_resample():只对训练集生成样本(测试集要保持真实,不能造)。

第十二步:打乱数据 + 保存为 Excel

python

运行

'''数据保存为excel文件'''
data_train = pd.concat([os_y_train, os_x_train], axis=1).sample(frac=1, random_state=4)
# sample() 方法用于从DataFrame中随机抽取行。frac: 表示抽取行的比例。
data_test = pd.concat([y_test_fill, x_test_fill], axis=1)  # 测试集不用传入模型训练,无需打乱顺序。

data_train.to_excel(r'./temp_data/训练数据集[平均值填充].xlsx', index=False)
data_test.to_excel(r'./temp_data/测试数据集[平均值填充].xlsx', index=False)
  • pd.concat([os_y_train, os_x_train], axis=1):把训练标签和训练特征合并成一个表格(axis=1 表示按列合并);
  • .sample(frac=1, random_state=4):打乱训练集的行(frac=1 表示取全部行,只是打乱顺序),避免模型 “死记硬背” 顺序;
  • to_excel():保存为 Excel 文件:
    • r'./temp_data/...':保存到当前文件夹的 temp_data 子文件夹(要先创建这个文件夹!);
    • index=False:不保存行号(避免 Excel 里多一列无用的数字)。

补充:自定义 fill_data.py 怎么写?

新手可能卡在fill_data这个自定义文件,这里给最简单的平均值填充函数(直接复制到 fill_data.py 里):

python

运行

# fill_data.py 文件内容
import pandas as pd
import numpy as np

# 训练集平均值填充
def mean_train_fill(x_train, y_train):
    # 按列计算平均值,填充空值
    x_train_filled = x_train.fillna(x_train.mean())
    return x_train_filled, y_train

# 测试集平均值填充(用训练集的平均值!)
def mean_test_fill(x_train_filled, y_train_filled, x_test, y_test):
    # 用训练集的平均值填充测试集
    x_test_filled = x_test.fillna(x_train_filled.mean())
    return x_test_filled, y_test

# 只保留完整行(可选)
def cca_train_fill(x_train, y_train):
    # 删除有空值的行
    x_train_clean = x_train.dropna()
    # 同步删除y_train中对应行
    y_train_clean = y_train.loc[x_train_clean.index]
    return x_train_clean, y_train_clean

def cca_test_fill(x_train_fill, y_train_fill, x_test, y_test):
    x_test_clean = x_test.dropna()
    y_test_clean = y_test.loc[x_test_clean.index]
    return x_test_clean, y_test_clean

运行代码的前置准备

  1. 安装需要的包(打开 cmd / 终端,复制粘贴):

bash

运行

pip install pandas numpy scikit-learn imblearn openpyxl
  1. 准备文件:
    • 把矿物数据保存为 “矿物数据.xls”,和代码放同一文件夹;
    • 创建temp_data文件夹(用来存处理后的 Excel);
    • 创建fill_data.py,把上面的填充函数复制进去。
  2. 直接运行主代码即可。

避坑指南

  1. 文件路径错:比如 Excel 文件不在同一文件夹,或 temp_data 文件夹没创建;
  2. 包没装全:比如没装 imblearn,运行 SMOTE 会报错;
  3. 中文乱码:保存 Excel 时如果乱码,可加encoding='utf-8'
  4. 缺失值填充错:测试集一定要用训练集的平均值,不能自己算!

总结

  1. 数据预处理核心逻辑:先清理(删异常、转格式)→ 再补全(填缺失值)→ 再标准化 → 最后划分保存
  2. 关键注意点:测试集和训练集要分开处理、样本不均衡用 SMOTE 解决、标签要转成数字;
  3. 新手不用死记代码,重点理解 “为什么做这一步”—— 所有操作都是为了让数据符合模型的要求
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐