Chapter 10 — Lab 3
缺失值与异常值 · 类型转换 · 数据清洗
掌握数据清洗的完整流程:检查→识别→处理→验证
学会使用 d3.filter()、Array.map() 对脏数据进行处理
理解常见数据质量问题及其处理策略
能够对原始数据进行规范化与类型转换
真实数据总是不完美的——有缺失值、有异常值、有格式混乱。本阶段你需要系统性地诊断数据问题,并使用 D3 / JavaScript 将脏数据转换为干净的分析数据集。
加载数据后,在浏览器控制台执行系统性检查:
// ① 检查缺失值
const missing = data.filter(d =>
Object.entries(d).some(([k, v]) => v === null || v === '')
);
console.log(`缺失值记录: ${missing.length}`);
// ② 检查异常值
const outliers = data.filter(d => d.year < 1900 || d.year > 2025);
console.log(`年份异常记录: ${outliers.length}`);
// ③ 检查重复记录
const keys = data.map(d => JSON.stringify(d));
const unique = new Set(keys);
console.log(`重复记录: ${data.length - unique.size}`);
将以上检查结果截图写入实验报告。
根据字段重要性选择处理策略:
// 策略一:直接删除(适用于缺失比例 < 5%)
data = d3.filter(data, d =>
d.year != null && d.value != null
);
// 策略二:用均值/中位数填充
const meanVal = d3.mean(data, d => d.value);
data.forEach(d => {
if (d.value == null) d.value = meanVal;
});
// 策略三:用特殊值标记(保留信息)
data.forEach(d => {
if (d.category == null) d.category = 'Unknown';
});
// 策略四:删除异常值
data = d3.filter(data, d =>
d.year >= 1900 && d.year <= 2025 && d.value >= 0
);
将原始数据转换为适合可视化的结构:
// ① 字段重映射
data = data.map(d => ({
year: +d.year,
name: d.name || 'Unknown',
value: +d.value || 0,
category: d.type ? d.type.trim() : 'Other'
}));
// ② 生成派生字段
data = data.map(d => ({
...d,
logValue: Math.log10(d.value + 1),
yearDecade: Math.floor(d.year / 10) * 10
}));
// ③ 数值规范化 [0, 1]
const [min, max] = d3.extent(data, d => d.value);
data = data.map(d => ({
...d,
normValue: (d.value - min) / (max - min)
}));
清洗完成后,回答以下检查项(写入实验报告):
□ 原始数据总量:______ 条
□ 清洗后数据总量:______ 条(删除了 ______ 条)
□ 各数值字段的 min / max / mean:
□ 分类字段的唯一值数量:
□ 是否还有缺失值(Y/N):
□ 数据是否已准备好进入可视化阶段(Y/N):
将清洗后的数据前 10 行截图附在报告中。
数据清洗的结果应可复现——在实验报告中记录所有操作步骤(filter / map / 填充值),注明决策理由。
实验报告(Word 填写): ① 数据质量检查截图(控制台输出) ② 数据清洗方法描述(文字 + 代码截图) ③ 清洗前后数据量对比 ④ 清洗后数据样本(前 10 行截图)