4. 数据剖析与探索:用Pandas看清数据全貌

拿到一份设备目录数据,别急着动手清洗。我个人的习惯是——先花10分钟做一次「数据体检」。说白了,就是搞清楚数据长什么样、哪里有问题、哪些字段值得深挖。这一步做扎实了,后面的清洗工作才能有的放矢。

今天我们就用Pandas这把瑞士军刀,把数据剖析这件事拆开揉碎了讲。我会带着你从概览、统计描述、缺失值、唯一值四个维度,把设备目录数据摸个透。

核心思路:数据剖析不是炫技,而是为了回答三个问题——数据完整吗?数据合理吗?数据能用吗?

数据剖析与探索知识框架 数据剖析与探索 数据概览 统计描述 缺失值统计 唯一值分析 head() / tail() shape / dtypes describe() isnull().sum() nunique() 数据剖析四步走 ① 看头看尾 → 了解数据长什么样 ② 统计描述 → 数值字段的分布特征 ③ 缺失值统计 → 数据完整度评估 ④ 唯一值分析 → 字段的区分度与质量

4.1 数据概览:先看头,再看尾

我每次拿到新数据集,第一件事就是敲 df.head()。这就像翻开一本书的目录,能快速知道数据有哪些列、每列大概长什么样。

import pandas as pd

# 读取设备目录数据
df = pd.read_csv('device_catalog.csv')

# 查看前5行
print(df.head())

# 查看后5行
print(df.tail())

# 查看数据集的形状(行数, 列数)
print(f"数据集形状: {df.shape}")

# 查看每列的数据类型
print(df.dtypes)

嗯,这里要注意——head() 默认显示5行,但你可以传参 head(10) 看更多。我个人习惯先看10行,因为5行有时候样本量太小,看不出规律。

我在项目中遇到过一件事:有次看 head() 觉得数据挺干净,结果 tail() 一翻,最后100行全是空值。你想想看,如果只看开头就下结论,后面得踩多大坑?

小技巧:用 df.sample(5) 随机抽取5行,能避免数据排序带来的「幸存者偏差」。

4.2 统计描述:用 describe() 读懂数值

describe() 是我最常用的函数之一。它自动计算数值列的均值、标准差、四分位数等统计量。说白了,就是给数据做一次「体检报告」。

# 默认只统计数值列
print(df.describe())

# 如果想看所有列(包括对象类型),加参数
print(df.describe(include='all'))

输出结果长这样(以设备价格字段为例):

统计量 价格(元) 库存数量 设备重量(kg)
count 980 1000 850
mean 12500.50 45.20 12.30
std 3200.80 18.50 5.60
min 0.00 0 0.50
25% 9800.00 30 8.20
50% 12000.00 42 11.80
75% 15000.00 58 15.40
max 999999.00 200 50.00

看到这个表格,你发现了什么?

  • count 不一致:价格只有980条,库存有1000条——说明价格字段有20个缺失值。
  • min 为0:价格最小值是0,这合理吗?设备价格不可能免费吧?
  • max 异常:价格最大值是999999,明显是异常值。我遇到过类似情况,后来发现是录入时多按了几个9。

注意:describe() 只能帮你「发现」异常,不能「解释」异常。看到不合理的数据,一定要结合业务逻辑去判断。

4.3 缺失值统计:数据完整度的照妖镜

缺失值处理是数据清洗的重头戏。第一步,先搞清楚哪些列有缺失、缺了多少。

# 统计每列的缺失值数量
missing_count = df.isnull().sum()
print(missing_count)

# 计算缺失比例
missing_ratio = df.isnull().sum() / len(df) * 100
print(missing_ratio)

# 把结果拼在一起看
missing_df = pd.DataFrame({
    '缺失数量': missing_count,
    '缺失比例(%)': missing_ratio
})
print(missing_df[missing_df['缺失数量'] > 0])

输出示例:

字段名 缺失数量 缺失比例(%)
设备名称 5 0.5
设备型号 120 12.0
价格 20 2.0
生产日期 350 35.0

看到这个结果,我的第一反应是:

  • 设备名称缺失0.5%,可以忽略或直接填充「未知设备」。
  • 设备型号缺失12%,需要找业务方确认是否有默认值。
  • 生产日期缺失35%——这问题大了。我曾经处理过类似的数据,后来发现是因为老设备没有录入生产日期。这种情况下,直接删除会损失太多数据,我建议标记为「未知」或单独分组处理。

经验之谈:缺失比例低于5%的字段,可以直接删除缺失行或用均值/众数填充。超过30%的字段,就要慎重了——删除会损失大量信息,填充又可能引入偏差。

4.4 唯一值分析:字段的区分度与质量

唯一值分析能告诉你两件事:字段的区分度好不好,以及有没有脏数据。

# 查看每列的唯一值数量
unique_counts = df.nunique()
print(unique_counts)

# 查看某个字段的具体唯一值
print(df['设备类型'].unique())

# 统计唯一值的频次
print(df['设备类型'].value_counts())

举个例子,假设「设备类型」字段的结果是这样的:

设备类型
服务器        450
交换机        320
路由器        280
路由器        1     # 注意:多了一个空格
Server        5     # 中英文混用
服务器          3     # 全角空格
Name: 设备类型, dtype: int64

你看,明明只有3种设备类型,却出现了6个不同的值。这就是典型的脏数据问题——空格、大小写、中英文混用。

我遇到过更离谱的:有个字段叫「设备状态」,理论上只有「正常」「维修」「报废」三种,结果 unique() 一看,有17种!仔细排查发现,有人填了「正常使用」「已报废」「维修中」等等。你想想看,如果不做唯一值分析,这种问题根本发现不了。

核心结论:唯一值分析是数据质量的第一道防线。如果唯一值数量远大于业务预期,大概率是数据录入不规范。

4.5 实战:把四步走串起来

好了,理论讲完了。我们用一个完整的例子,把今天学的四步走串起来。

import pandas as pd

# 1. 加载数据
df = pd.read_csv('device_catalog.csv')

# 2. 数据概览
print("=== 数据概览 ===")
print(f"数据集大小: {df.shape}")
print(f"列名: {df.columns.tolist()}")
print(f"数据类型:\n{df.dtypes}")
print(f"\n前5行:\n{df.head()}")

# 3. 统计描述
print("\n=== 统计描述 ===")
print(df.describe(include='all'))

# 4. 缺失值统计
print("\n=== 缺失值统计 ===")
missing = df.isnull().sum()
missing_pct = (missing / len(df)) * 100
missing_report = pd.DataFrame({'缺失数量': missing, '缺失比例(%)': missing_pct})
print(missing_report[missing_report['缺失数量'] > 0].sort_values('缺失比例(%)', ascending=False))

# 5. 唯一值分析
print("\n=== 唯一值分析 ===")
for col in df.columns:
    unique_count = df[col].nunique()
    print(f"{col}: {unique_count} 个唯一值")
    if unique_count < 20:  # 唯一值少的字段,打印具体值
        print(f"  具体值: {df[col].unique()}")

这段代码我几乎每个项目都会用。把它封装成一个函数,以后每次拿到新数据,跑一遍就心里有数了。

建议:把上面的代码保存为 data_profile.py,以后每次做数据清洗前先跑一遍。我自己的工具箱里就有这个脚本,用了三年,省了不少时间。

4.6 避坑指南

最后,分享几个我踩过的坑:

  • 别只看 describe() 的均值:均值容易被极端值拉偏。我遇到过一批设备价格,均值显示1.2万,但实际大部分设备在8000左右,因为有几个100万的异常值把均值拉高了。一定要结合中位数和四分位数一起看。
  • 缺失值统计要关注「隐式缺失」:有些数据不是 NaN,而是用「-」「未知」「0」代替。这些在 isnull() 里是统计不到的。我建议对关键字段做一次 value_counts(),看看有没有异常占位符。
  • 唯一值分析要区分「业务唯一」和「技术唯一」:比如设备编号,技术上应该是唯一的,但如果发现重复值,可能是数据录入错误。而设备颜色,重复是正常的,不需要处理。

数据剖析这件事,说白了就是「先调查,再动手」。花10分钟做一次全面体检,能帮你避免后面几小时的返工。记住我这句话:数据清洗的80%问题,在剖析阶段就能发现。