Chapter 11 — Lab 4
数据筛选 · 分组聚合 · 数据处理管道
掌握 d3.bin() 分箱方法,将连续数据离散化
熟练使用 d3.groups()、d3.rollup() 对数据做分组聚合
理解标准化、采样、降维等高级数据处理概念
能够构建清晰的数据处理管道(pipeline)
可视化不可能展示所有数据的全部细节。本阶段你需要学会「选择展示什么、聚合什么、隐藏什么」——这是数据可视化的核心技术,也是区分初学者和有经验开发者的关键。
根据分析目标,设置时空或属性过滤条件:
// 时序过滤:只保留特定时间范围
data = d3.filter(data, d =>
d.year >= 2000 && d.year <= 2020
);
// 数值过滤:剔除极端值
data = d3.filter(data, d =>
d.value >= d3.quantile(sortedValues, 0.01) &&
d.value <= d3.quantile(sortedValues, 0.99)
);
// 分类过滤:只保留特定类别
const targets = ['Cat A', 'Cat B'];
data = d3.filter(data, d => targets.includes(d.category));
使用 d3.bin() 将连续变量离散化,生成直方图数据:
const bins = d3.bin()
.domain([minVal, maxVal])
.thresholds(10)
.value(d => d.value)
(data);
// bins = [{x0, x1, length}, ...]
// 直接用于 SVG bar chart:
svg.selectAll('rect')
.data(bins).join('rect')
.attr('x', d => xScale(d.x0))
.attr('width', d => xScale(d.x1) - xScale(d.x0))
.attr('y', d => yScale(d.length))
.attr('height', d => height - yScale(d.length));
尝试不同的 threshold 数量(5/10/20),观察哪个最能展示数据分布特征。
使用 d3.groups() 按一个或多个维度聚合数据:
// 按单个字段分组
const byCategory = d3.groups(data, d => d.category);
// 分组并计算聚合值
const aggregated = d3.groups(data, d => d.category)
.map(([cat, items]) => ({
name: cat,
count: items.length,
avgValue: d3.mean(items, d => d.value)
}))
.sort((a, b) => b.count - a.count);
// d3.rollup() 更高效(返回 Map)
const rolled = d3.rollup(data,
v => v.length,
d => d.category
);
当数据量超过 3000 条时,随机采样可以显著提升渲染性能:
// 随机采样
function sample(data, n) {
return d3.shuffle([...data]).slice(0, n);
}
const sampled = sample(data, 2000);
// 分层采样(保持各分类比例)
const stratified = d3.groups(data, d => d.category)
.flatMap(([cat, items]) =>
d3.shuffle([...items]).slice(0, Math.ceil(items.length * 0.3))
);
在实验报告中说明:原始数据量、是否采样、方法和样本量。
数据处理管道的设计原则:先过滤 → 再聚合 → 最后可视化。在图表渲染阶段做 filter 会导致每次交互都重新加载所有数据,应在数据准备阶段完成所有筛选。
实验报告(Word 填写): ① 过滤条件及理由 ② 分箱/聚合策略说明(文字 + 代码截图) ③ 各分组聚合结果表格 ④ 是否采样及采样方法说明