第二章:数据准备——如何获取和整理批次数据
说实话,数据可视化这件事,数据占七分,可视化只占三分。我在团队里带新人,发现他们最爱一上来就调颜色、选图表,结果数据一跑全是乱码,那画面……嗯,我才意识到,数据准备这关没过去,后面全是白忙活。
2.1 数据来源:你的批次数据从哪来?
批次数据的获取方式,取决于你所在的环境。我根据项目经验,把它们归成了三类。你想想看,你的数据属于哪一类?
| 数据来源类型 | 典型场景 | 个人建议 |
|---|---|---|
| 日志文件(.csv、.log、.json) | 生产线每一批的质检记录、服务器请求日志 | 直接读取最省事,但注意文件编码问题 |
| 数据库查询(MySQL、PostgreSQL、SQLite) | ERP系统里的订单批次、仓库出入库流水 | 用SQL取数时,记得按时间字段排序 |
| 实时流数据(Kafka、MQTT) | IoT设备上报的生产批次、传感器读数 | 需要先做物化视图或简单聚合 |
我个人习惯,先用一个简单脚本把数据拉下来,看看数据长什么样。
import pandas as pd
# 从CSV读批次数据
df = pd.read_csv('batch_records_202501.csv')
print(df.head())
print(df.info())
这一步能帮你快速确认有多少个字段、每个字段的类型对不对。我见过有人直接拿Excel打开大CSV,结果活活卡死……用代码来预览,效率高得多。
2.2 清洗与预处理:把脏数据“洗干净”
数据清洗嘛,说白了就是跟各种脏数据斗智斗勇。我遇到过最头疼的情况:一个订单批次的“生产时间”字段,里面混了“未知”“2025/01/01”“2025-01-01”三种格式,还有个格子干脆填了“昨天”。
标准化流程,我一般分四步:
- 去除空值和无效值——丢掉那种全是空的行,或者某些关键字段缺失的行。
- 统一数据类型——时间格式、数字单位全部转成一致。
- 剔除明显异常值——比如批次编号出现负数,或者产量超过了生产线理论最大值。
- 检查唯一性和重复——确认批次ID没有重复项。
下面这段代码,是我做批次数据清洗时常用的骨架:
# 1. 去除空值
df_clean = df.dropna(subset=['batch_id', 'production_time'])
# 2. 统一时间格式
df_clean['production_time'] = pd.to_datetime(
df_clean['production_time'],
format='mixed',
errors='coerce'
)
# 3. 剔除产量为负的异常行
df_clean = df_clean[df_clean['output_qty'] > 0]
# 4. 去重
df_clean = df_clean.drop_duplicates(subset=['batch_id'])
print(f"清洗前 {len(df)} 行,清洗后 {len(df_clean)} 行")
2.3 数据变换:让批次数据可视化更顺手
数据结构转换这块,我个人习惯根据后续图表的需求来做。比如你想画一张“各批次合格率分布”,那最好把数据弄成每行一个批次的宽表格式。
如果原始数据是长格式(每行是一条检测记录),需要用pivot来转一下:
df_wide = df_clean.pivot_table(
index='batch_id',
columns='metric_name',
values='metric_value'
).reset_index()
做过几次你就明白了——数据跟图表之间,少一步转换都可能出问题。我曾经因为忘记重置索引,导致批次ID丢失,整张图的x轴标签全乱了。
2.4 一个避坑:批次编号的命名规则
很多企业习惯把批次编号写得很随意,比如“B202501-A”、“B202501A”、“B-202501-A”……这几种写法你看着相似,但机器会认为是三个不同的批次。
import re
def normalize_batch_id(raw_id):
# 只保留字母和数字,统一大写
clean_id = re.sub(r'[^A-Za-z0-9]', '', str(raw_id)).upper()
# 如果短于6位,补零对齐
return clean_id.zfill(6)
df_clean['batch_id_std'] = df_clean['batch_id'].apply(normalize_batch_id)
2.5 知识结构图:批次数据准备的核心流程
下面的图,是我自己总结的数据准备阶段核心逻辑。每个环节对应一个关键操作,箭头方向就是数据处理的方向。
2.6 常用脏数据模式速查表
这里我列了一个速查表,都是我在实际项目中反复遇到的情况。以后你碰到类似问题,可以快速对应处理:
| 数据问题 | 表现 | 解决思路 |
|---|---|---|
| 空值/缺失 | 某一批次的关键指标是NaN | 直接dropna()或填充中位数/众数 |
| 字段类型混乱 | 数字列里混了字符串 | pd.to_numeric(errors='coerce') |
| 时间格式不统一 | “2025/01/01”和“2025-01-01”并存 | 统一parse或强制转datetime |
| 重复批次 | 同一个batch_id出现了多次 | 按生产时间取最近一次或保留第一次 |
| 单位不一致 | 产量有的写“箱”,有的写“吨” | 建立换算关系,统一到一个单位 |
2.7 整合数据集:为可视化做好准备
等前面几步都做完,你就可以把清洗后的数据整合成一份“干净的批次分布数据集”。我个人习惯把所有字段列成清单,确保没有遗漏:
final_columns = [
'batch_id', # 批次编号
'production_date', # 生产日期
'product_line', # 产线
'target_qty', # 目标产量
'output_qty', # 实际产量
'defect_qty', # 缺陷数量
'pass_rate', # 合格率
'cycle_time_min' # 周期时间(分钟)
]
df_final = df_clean[final_columns].copy()
好了,到这一步,批次数据已经备好,可以拿去画图了。嗯,数据准备虽然不是最炫酷的活儿,但它是一切的根基。你想想看,如果数据没洗干净,后面那些漂亮的图表、交互设计,不过是“垃圾进,垃圾出”罢了。