3.4 信息系统的数据处理
知识点
1.处理是系统的"分水岭"
输入进来的是"原料",输出出去的是"产品",处理就是中间的加工线。
同样的数据,处理方式不同,结论可能完全相反:
| 问题 | 错误处理 | 正确处理 |
|---|---|---|
| 各班平均分 | 直接把所有分数相加除以人数(漏掉缺考) | 排除缺考、按班分组再求平均 |
| 图书馆借阅排行 | 按"借阅次数"排 | 排除内部调拨与测试记录 |
| 设备温度告警 | 单次超阈值就报警 | 连续三次超阈值才报警(过滤抖动) |
结论:数据处理不是"算一下",而是"按业务规则算对"。
2.数据处理的完整流程(六步,必背)
采集 → 清洗 → 转换 → 统计/加工 → 存储 → 输出
| 步骤 | 做什么 | 典型操作 |
|---|---|---|
| 采集 | 把数据汇集到处理环境 | 导入、接口拉取、实时接收 |
| 清洗 | 去掉"脏"的部分 | 处理缺失、异常、重复 |
| 转换 | 统一格式与口径 | 类型转换、单位换算、编码统一 |
| 统计/加工 | 按业务规则计算 | 汇总、分组、排序、计算派生字段 |
| 存储 | 保存结果供复用 | 写入结果表、建索引 |
| 输出 | 交给呈现层 | 接口返回、生成报表数据集 |
学生最容易漏的是"清洗"——直接从采集跳到统计,结果一定出错。经验值:真实项目中清洗往往占全部工作量的一半以上。
3.数据清洗(本节重点)
(1)缺失值
| 情况 | 处理方式 | 说明 |
|---|---|---|
| 缺失比例极低(如 1%) | 删除该条记录 | 简单,几乎不影响结果 |
| 数值型字段缺失 | 用均值/中位数/众数填充 | 保留样本量,但可能引入偏差 |
| 有前后关系(如时间序列) | 用前一个值填充 | 适合传感器短时缺测 |
| 关键字段缺失(如学号) | 必须补录或退回 | 不能猜,猜就是造假 |
注意:"缺考"和"0 分"是两回事。把缺考填成 0,会严重拉低平均分——这是教学数据统计里最常见的错误。
(2)异常值
| 判断方法 | 说明 | 举例 |
|---|---|---|
| 业务范围判断 | 超出常识范围即为异常 | 年龄 200 岁、成绩 150 分 |
| 阈值判断 | 超出设定上下限 | 温度 -40 ℃ 以下(传感器故障) |
| 统计方法 | 偏离均值过多(如 3 倍标准差) | 消费金额异常巨大 |
| 对比判断 | 与同类数据差异过大 | 同班身高 2.3 m |
处理策略(三种,要分清):
- 删除——确认是错误数据(如录入错误);
- 修正——能推断出正确值(如单位录错,厘米写成米);
- 保留并标记——可能是真实极端值(如个别超高消费),不能随便删。
关键提醒:异常 ≠ 错误。真实世界确实存在极端情况,不加判断地删除异常值,可能把最有价值的信息删掉了(如欺诈交易本身就是"异常")。
(3)重复值
| 类型 | 说明 | 处理 |
|---|---|---|
| 完全重复 | 所有字段都一样 | 直接去重 |
| 关键字段重复 | 学号相同但其他不同 | 需判断保留哪条(通常留最新) |
| 业务重复 | 同一天同一人重复刷卡 | 按业务规则合并 |
去重前先想清楚"什么算重复"——是"学号相同"算重复,还是"学号+日期"相同才算?这决定了去重结果对不对。
(4)格式不一致
- 全角/半角混用("张 明"与"张明");
- 空格、不可见字符;
- 单位不统一(米/厘米、元/万元);
- 编码不统一(
UTF-8/GBK乱码)。
处理手段:去空格、统一大小写、统一单位、统一编码、正则替换。
4.数据转换
| 转换类型 | 说明 | 举例 |
|---|---|---|
| 类型转换 | 文本转数字/日期 | "85" 转 85 才能求和 |
| 单位换算 | 统一计量单位 | 厘米统一为米 |
| 编码映射 | 代码转名称 | 1 → "男","A" → "优秀" |
| 格式规范 | 统一写法 | 日期统一为 YYYY-MM-DD |
| 派生字段 | 由已有字段算出新字段 | 由出生日期算年龄;由借还日期算是否逾期 |
| 数据分箱 | 连续值分段 | 成绩分为"优秀/良好/及格/不及格" |
派生字段的价值:把"计算"前置到数据层,后续查询与统计就不用重复算。但同时要注意 "一处算错、处处错",派生字段的口径必须写进文档。
5.用 SQL 做统计(最常用)
五个聚合函数:COUNT、SUM、AVG、MAX、MIN。
-- 各班人数与平均分(排除缺考:score IS NOT NULL)
SELECT class,
COUNT(*) AS 人数,
AVG(score) AS 平均分,
MAX(score) AS 最高分,
MIN(score) AS 最低分
FROM exam
WHERE score IS NOT NULL
GROUP BY class
ORDER BY 平均分 DESC;
四个关键点:
WHERE在分组前过滤行,HAVING在分组后过滤组;COUNT(*)数行数,COUNT(字段)不数NULL——统计"参加考试人数"必须用后者;AVG会自动忽略NULL,但填 0 会被算进去,所以"缺考填 0"是错的;- 日期统计要按区间筛,如
WHERE out_date BETWEEN '2026-09-01' AND '2026-09-30'。
进阶查询示例:
-- 逾期未还名单:应还日期早于今天且未归还
SELECT s.name, b.title, r.due_date
FROM borrow r
JOIN student s ON r.stu_id = s.stu_id
JOIN book b ON r.book_id = b.book_id
WHERE r.back_date IS NULL AND r.due_date < DATE('now');
-- 借阅排行前 10
SELECT b.title, COUNT(*) AS 次数
FROM borrow r JOIN book b ON r.book_id = b.book_id
GROUP BY b.title
ORDER BY 次数 DESC
LIMIT 10;
6.用 Python pandas 做处理
数据量大、清洗步骤多时,用 pandas 更灵活。
import pandas as pd
# 1. 读入
df = pd.read_csv("scores.csv", encoding="utf-8")
# 2. 看数据全貌:行数、列名、类型、缺失情况
print(df.shape, df.dtypes)
print(df.isnull().sum())
# 3. 清洗:成绩转数值,无法转换的变 NaN,再删掉
df["score"] = pd.to_numeric(df["score"], errors="coerce")
df = df.dropna(subset=["stu_id", "score"])
# 4. 去重
df = df.drop_duplicates(subset=["stu_id", "course"])
# 5. 派生字段:是否及格
df["pass"] = df["score"] >= 60
# 6. 分组统计
stat = df.groupby("class")["score"].agg(["count", "mean", "max", "min"])
print(stat)
对应关系(pandas 与 SQL 是一回事):
| 操作 | SQL | pandas |
|---|---|---|
| 筛选行 | WHERE | df[df["score"] > 60] |
| 选列 | SELECT 列 | df[["列1","列2"]] |
| 分组 | GROUP BY | groupby() |
| 聚合 | COUNT/SUM/AVG | agg(["count","sum","mean"]) |
| 排序 | ORDER BY | sort_values() |
| 连接 | JOIN | merge() |
教学建议:先会 SQL,再看 pandas——两者思想完全一致,只是写法不同。
7.批处理与实时处理
| 类型 | 处理时机 | 特点 | 适用 |
|---|---|---|---|
| 批处理 | 攒一批,定时处理 | 吞吐量大、延迟高、实现简单 | 期末成绩统计、日报月报、夜间对账 |
| 实时处理(流处理) | 数据一到就处理 | 延迟低、需持续运行、成本高 | 刷卡扣费、告警监测、实时大屏 |
选择的判断依据:
- 能等(分钟、小时级)→ 批处理;
- 不能等(秒级必须响应)→ 实时处理。
混合模式最常见:刷卡时实时扣款(实时),但统计"本月消费总额"放在夜间批处理。同一个系统里两种方式并存,是常态。
批处理的设计要点:
- 幂等——同一批数据重复跑,结果不变(否则会重复累加);
- 断点续跑——中途失败能从断点继续,不用全部重来;
- 处理窗口——放在业务低峰(如凌晨)执行;
- 结果核对——跑完核对总条数、总金额,防止"静默错误"。
8.数据加工的常用操作
| 操作 | 作用 | 举例 |
|---|---|---|
| 排序 | 按某字段排列 | 按成绩降序排名 |
| 筛选 | 按条件取子集 | 只看逾期记录 |
| 分组 | 按类别聚合 | 按班级、按月份 |
| 计算派生列 | 生成新指标 | 及格率、人均消费 |
| 连接(关联) | 多表拼接 | 借阅表+学生表+图书表 |
| 透视 | 行列互换做交叉表 | 班级 × 科目 的成绩表 |
| 合并/追加 | 多批数据合成一份 | 三个月流水合并 |
透视表的理解:把"行"的分类变成"列"的分类。例如原始数据是"每条消费记录一行",透视后变成"行是学生、列是月份、格子里是消费额"——这就是报表的常见形态。
9.处理结果的质量校验
处理完必须核对的四项:
| 核对项 | 方法 | 目的 |
|---|---|---|
| 总量核对 | 处理前后记录条数、金额合计是否一致 | 防丢数据、防重复 |
| 范围核对 | 结果是否落在合理区间 | 防计算错误 |
| 抽样核对 | 手工算几条对比程序结果 | 防逻辑错误 |
| 异常核对 | 有没有空值、负数、超范围值 | 防脏数据残留 |
"静默错误"最可怕:程序没报错、页面也正常,但数字是错的。唯一防线就是核对。
一个实用习惯:每次处理都输出一份"处理日志"——读了多少条、清洗掉多少条、异常多少条、结果多少条。这份日志在排查问题时价值极高。
10.处理环节的伦理与边界
| 问题 | 说明 |
|---|---|
| 数据造假 | 为了让指标好看而修改数据,是最严重的违规 |
| 过度推断 | 用相关关系当因果关系("冰淇淋销量高,溺水人数也多"——实际都受气温影响) |
| 选择性呈现 | 只报有利的数据,隐去不利的 |
| 隐私泄露 | 处理后的结果仍可能通过组合推断出个人身份 |
一条底线:处理数据的人,要对数据背后的人负责。 每一个数字都对应真实的人与事。
11.速查表
| 序号 | 考点 | 结论 |
|---|---|---|
| 1 | 处理流程六步 | 采集 → 清洗 → 转换 → 统计 → 存储 → 输出 |
| 2 | 最易被跳过的步骤 | 清洗(常占一半工作量) |
| 3 | 缺失值常见处理 | 删除、均值/中位数填充、前值填充、补录 |
| 4 | 缺考与 0 分 | 不是一回事,不能填 0 |
| 5 | 异常值三种策略 | 删除、修正、保留并标记 |
| 6 | 异常与错误的关系 | 异常不一定错误 |
| 7 | 去重前先明确 | 什么算重复 |
| 8 | 四类转换 | 类型、单位、编码映射、格式规范 |
| 9 | 派生字段 | 由已有字段算出(年龄、逾期天数) |
| 10 | 五个聚合函数 | COUNT、SUM、AVG、MAX、MIN |
| 11 | COUNT(*) 与 COUNT(字段) | 后者不统计 NULL |
| 12 | WHERE 与 HAVING | 分组前过滤行/分组后过滤组 |
| 13 | 分组关键字 | GROUP BY |
| 14 | pandas 分组 | groupby() + agg() |
| 15 | 批处理特点 | 吞吐大、延迟高,适合报表 |
| 16 | 实时处理特点 | 延迟低、成本高,适合扣费与告警 |
| 17 | 批处理设计要点 | 幂等、断点续跑、低峰执行、结果核对 |
| 18 | 最危险的错误 | 静默错误(不报错但结果错) |
| 19 | 结果校验四项 | 总量、范围、抽样、异常 |
| 20 | 常见逻辑谬误 | 把相关当因果 |
12.课堂提示(讲课参考)
- 用一份"脏成绩单"贯穿全课:准备 40 条数据,故意包含缺考、150 分、重复学号、姓名带空格、分数存成文本。让学生先直接求平均(结果明显荒谬),再一步步清洗。同一个数据集走完六个步骤,比六个孤立例子有效得多。
- "缺考填 0"要专门强调:让学生分别算"填 0"和"排除缺考"的平均分,两者差出十几分,冲击很直观。这是教学统计里最高频的错误。
SQL与pandas对照讲:同一道题(按班求平均分)两种写法并排投影,学生会发现"原来只是换了语法"。对基础弱的学生,这能显著降低畏难情绪。- "静默错误"建议做一次事故演练:给出一个"看起来正常"的报表,让学生抽查三条原始记录手算,发现数字对不上(因为某个
JOIN造成了重复计数)。多表连接导致行数膨胀是真实项目里最常见的坑。 - 批处理与实时用"食堂"类比:刷卡时实时扣款(不能等),月底统计消费总额放夜间跑(能等)。一句话就把两种模式的分工说清了。