数据加载与初步探索:用Pandas打开材料数据的大门
做材料数据清洗,第一步是什么?
不是写清洗逻辑,也不是搞特征工程。而是——先把数据读进来,看看它长什么样。
我见过太多人,拿到一个CSV文件就直接开始写处理代码,结果跑了一半才发现列名不对、数据类型错了、缺失值一堆。嗯,这种坑我踩过不止一次。所以今天这节课,咱们就老老实实从数据加载和初步探索开始。
2.1 读取CSV文件:最常用的操作
材料数据最常见的存储格式就是CSV。为什么?因为简单、通用,Excel也能打开。Pandas读取CSV用pd.read_csv(),这个函数参数很多,但常用的就那几个。
import pandas as pd
# 读取材料成分数据
df = pd.read_csv('material_composition.csv')
# 如果文件路径有中文,记得加 encoding 参数
df = pd.read_csv('材料数据.csv', encoding='utf-8')
# 如果分隔符不是逗号,比如是制表符
df = pd.read_csv('data.tsv', sep='\t')
我个人习惯,读取数据后第一件事就是看数据量。用df.shape看一眼,几行几列心里有个数。
nrows=1000 先读前1000行看看结构,避免内存爆炸。
2.2 读取Excel文件:处理多工作表
材料实验室的数据,很多还是存在Excel里的。而且经常一个文件里好几个sheet,什么「成分表」、「热处理工艺」、「力学性能」全塞在一起。
# 读取第一个sheet
df = pd.read_excel('材料数据.xlsx')
# 指定sheet名
df = pd.read_excel('材料数据.xlsx', sheet_name='成分表')
# 读取所有sheet,返回一个字典
sheets = pd.read_excel('材料数据.xlsx', sheet_name=None)
我记得有一次,合作方给了一个Excel文件,里面20多个sheet,命名还不规范。我直接用sheet_name=None全部读进来,然后遍历处理,省了不少事。
pip install openpyxl。
2.3 head():看一眼数据长啥样
数据读进来了,先别急着分析。用head()看一眼前几行,确认列名对不对、数据格式对不对。
# 查看前5行(默认)
df.head()
# 查看前10行
df.head(10)
# 查看最后5行
df.tail()
这一步能发现很多问题。比如列名里有空格、有特殊字符、或者数据类型明显不对。我遇到过一列「温度」,里面居然混了「25℃」、「25」、「25.0」三种写法——这就是清洗的信号。
2.4 info():快速掌握数据类型和缺失情况
info()是我用得最多的方法之一。它能告诉你:每列的数据类型、有多少非空值、内存占用。
df.info()
输出大概长这样:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5000 entries, 0 to 4999
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 成分_A 5000 non-null float64
1 成分_B 5000 non-null float64
2 成分_C 4998 non-null float64
3 热处理温度 5000 non-null int64
4 热处理时间 5000 non-null float64
5 硬度 4995 non-null float64
6 抗拉强度 5000 non-null float64
7 备注 1200 non-null object
dtypes: float64(6), int64(1), object(1)
memory usage: 312.5 KB
看到什么了?
- 成分_C 有2个缺失值
- 硬度有5个缺失值
- 备注列只有1200个非空,说明大部分是空的
- object类型的那一列,通常是文本,要小心处理
我曾经接手一个材料数据库,info一看,有一列「密度」居然是object类型。查了半天,发现里面混了「7.8g/cm³」这样的字符串。这就是典型的脏数据。
2.5 describe():数值列的统计摘要
describe()对数值列做统计描述:计数、均值、标准差、最小值、四分位数、最大值。
df.describe()
输出示例:
| 成分_A | 成分_B | 硬度 | 抗拉强度 | |
|---|---|---|---|---|
| count | 5000.0 | 5000.0 | 4995.0 | 5000.0 |
| mean | 0.35 | 0.22 | 58.4 | 420.3 |
| std | 0.12 | 0.08 | 12.1 | 85.6 |
| min | 0.01 | 0.00 | 22.0 | 180.0 |
| 25% | 0.25 | 0.15 | 48.0 | 360.0 |
| 50% | 0.34 | 0.21 | 57.0 | 415.0 |
| 75% | 0.44 | 0.28 | 67.0 | 475.0 |
| max | 0.98 | 0.95 | 95.0 | 720.0 |
这里能发现什么?
- 成分_A 最大0.98,最小0.01,范围合理
- 硬度最小值22,最大值95,跨度大——是不是有不同材料体系混在一起?
- 抗拉强度均值420,标准差85——数据分布还算正常
如果某个数值列的最小值是负数,或者最大值异常高,那就要警惕了。我遇到过一列「弹性模量」,最大值居然标了99999,明显是录入错误。
2.6 数据类型概览:别让类型坑了你
Pandas的数据类型和Python原生类型不太一样。常见的有:
- int64:整数
- float64:浮点数
- object:字符串或混合类型
- datetime64:日期时间
- category:分类数据
查看每列类型:
df.dtypes
为什么类型重要?
你想想看,如果一列「热处理温度」是object类型,你去做加减乘除就会报错。如果一列「日期」是object,你没法按时间排序。
类型转换示例:
# 将字符串转为数值
df['温度'] = pd.to_numeric(df['温度'], errors='coerce')
# 将字符串转为日期
df['实验日期'] = pd.to_datetime(df['实验日期'])
# 将文本转为分类
df['材料类型'] = df['材料类型'].astype('category')
我曾经处理过一批材料数据,里面「成分含量」列是字符串,比如「12.5%」。直接用pd.to_numeric会报错。我的做法是先去掉百分号,再转成浮点数,最后除以100。这种细节,不注意就会翻车。
知识体系总览
下面这张图,把本章的核心逻辑串起来了:
小结一下
这一章的内容其实就四个动作:
- 读进来——用read_csv或read_excel
- 看一眼——用head()确认数据样子
- 摸个底——用info()看类型和缺失
- 算个账——用describe()看数值分布
做完这四步,你对数据就有了基本判断。哪些列需要清洗,哪些列可以直接用,心里就有数了。
说白了,数据探索就像医生看病前的「望闻问切」。别急着开药方,先搞清楚病人什么情况。这个习惯,能帮你省下后面80%的麻烦。