3. 数据清洗与预处理:别让脏数据毁了你的仪表盘
说实话,我见过太多人一上来就急着画图表、搭仪表盘。结果呢?数据一跑,全是乱码,指标对不上,趋势线像心电图。嗯,问题多半出在数据清洗这一步。
我个人习惯,拿到数据的第一件事不是看它有多漂亮,而是先问三个问题:数据全不全?数据准不准?数据格式对不对? 这三个问题搞不定,后面的一切都是白搭。
3.1 数据质量检查:先给你的数据做个“体检”
数据质量检查,说白了就是看看你的数据有没有“生病”。我一般会从四个维度入手:
- 完整性: 有没有缺失值?比如某个字段是空的。
- 准确性: 数据值是否合理?比如年龄字段出现 200 岁。
- 一致性: 同一字段的格式是否统一?比如日期有的是 "2024-01-01",有的是 "01/01/2024"。
- 唯一性: 有没有重复记录?比如同一条订单出现了两次。
我在项目中遇到过最坑的一次,是某个销售系统的订单金额字段,居然混入了文本描述,比如 "100元"、"约200块"。你想想看,这种数据直接做聚合,结果能对吗?
所以,第一步永远是先跑一个数据概览。用 Python 的话,我习惯这样写:
import pandas as pd
# 加载数据
df = pd.read_csv('risk_data.csv')
# 快速概览
print(df.info()) # 查看列名、非空数量、数据类型
print(df.describe()) # 数值列的统计摘要
print(df.head()) # 看看前几行长什么样
这段代码跑完,你基本就能知道数据有没有“硬伤”了。
3.2 缺失值处理:别让“空”字毁了你的计算
缺失值,是数据清洗里最常遇到的问题。为什么会缺失?原因很多:系统没采集到、用户没填写、数据传输过程中丢了……
处理缺失值,我一般有三种策略:
| 策略 | 适用场景 | 代码示例 |
|---|---|---|
| 直接删除 | 缺失比例很小(<5%),且不影响整体分析 | df.dropna(inplace=True) |
| 填充均值/中位数 | 数值型字段,缺失比例适中 | df['age'].fillna(df['age'].median(), inplace=True) |
| 填充众数 | 分类字段,比如“性别”、“地区” | df['gender'].fillna(df['gender'].mode()[0], inplace=True) |
3.3 异常值检测:揪出那些“不听话”的数据点
异常值,就是那些明显偏离正常范围的数据。比如,风险评分正常在 0-100 之间,突然冒出一个 999。这种数据不处理,仪表盘上的图表会被它“带偏”。
我常用的检测方法有两种:
- 3σ 原则: 适用于数据近似正态分布。超出均值 ±3 个标准差的值,视为异常。
- 箱线图法(IQR): 适用于任何分布。超出 Q1 - 1.5*IQR 或 Q3 + 1.5*IQR 的值,视为异常。
代码实现也很简单:
# 箱线图法检测异常值
Q1 = df['risk_score'].quantile(0.25)
Q3 = df['risk_score'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
# 标记异常值
df['is_outlier'] = (df['risk_score'] < lower_bound) | (df['risk_score'] > upper_bound)
3.4 数据标准化:让不同量纲的数据“对齐”
实时风险仪表盘里,经常要同时展示多个指标。比如“交易金额”(单位:万元)和“风险评分”(单位:分)。这两个指标的量纲完全不同,直接放在一起比较,金额的波动会完全掩盖评分的细节。
标准化的目的,就是把不同量纲的数据映射到同一个尺度上。我常用的方法有两种:
| 方法 | 公式 | 适用场景 |
|---|---|---|
| Min-Max 标准化 | X' = (X - min) / (max - min) | 数据有明确边界,比如评分 0-100 |
| Z-score 标准化 | X' = (X - mean) / std | 数据分布近似正态,无明确边界 |
代码示例:
from sklearn.preprocessing import MinMaxScaler, StandardScaler
# Min-Max 标准化
scaler = MinMaxScaler()
df['amount_normalized'] = scaler.fit_transform(df[['amount']])
# Z-score 标准化
scaler = StandardScaler()
df['risk_score_normalized'] = scaler.fit_transform(df[['risk_score']])
我个人更推荐 Z-score,因为它对异常值不那么敏感。但如果你要展示的数据有明确的业务边界(比如风险评分不能超过 100),那 Min-Max 更直观。
3.5 知识体系总览
下面这张图,是我自己总结的数据清洗与预处理流程。你可以把它当作一个检查清单,每次做数据清洗时,按这个顺序走一遍,基本不会漏掉什么。
这张图的核心逻辑是:先检查,再处理,最后标准化。顺序不能乱。我见过有人先做标准化,再处理缺失值,结果标准化后的数据被缺失值“污染”了,白忙一场。
好了,这一章的内容就到这里。数据清洗虽然枯燥,但它是仪表盘稳定运行的基石。下一章,我们会聊聊如何设计实时数据管道,让数据“流”起来。