前哨站/第4章 数据准备与清洗
第4章 数据准备与清洗

第4章 数据准备与清洗

可视化的时间 80% 花在数据上:口径对齐、缺失处理、长宽表转换。

清洗聚合长宽表

本章学习目标

  • 能检查并处理缺失值、异常值、重复值
  • 能做数值归一化与分组聚合(分箱)
  • 能区分宽表与长表并按工具需要转换
  • 能对齐指标口径,保证图与结论一致

本章导览

核心内容

4.1

常见数据问题

五类高频问题
问题表现处理方式
缺失值空、NULL、—删除 / 填均值中位数 / 填业务默认值
异常值明显离群的极值先确认是否录入错误,再用箱线图规则处理
重复行同一条记录出现多次按主键去重(保留最新)
口径不一致同名指标算法不同统一口径并写在图注里
单位不一致元/万元、% / 小数统一单位后再画
4.2

清洗与转换

Excel、Python、SQL 三套工具做的是同一件事,思路完全一致。

4.2.1

缺失与异常处理

PYTHON
# Python:缺失值统计与填充
df.isna().sum()                       # 每列缺失数
df['sales'] = df['sales'].fillna(df['sales'].median())

# 异常值:按 1.5 倍四分位距识别
q1, q3 = df['sales'].quantile([0.25, 0.75])
iqr = q3 - q1
df = df[(df['sales'] >= q1 - 1.5 * iqr) & (df['sales'] <= q3 + 1.5 * iqr)]
SQL
-- SQL 等价写法
SELECT province, coalesce(sum(sales), 0) AS sales
FROM orders GROUP BY province;
4.2.2

聚合、分箱与归一化

PYTHON
# 分组聚合
g = df.groupby('province', as_index=False)['sales'].sum().sort_values('sales', ascending=False)

# 数值分箱(把连续值变成有序类别)
df['price_band'] = pd.cut(df['price'], bins=[0, 50, 100, 500, 1e9],
                          labels=['<50', '50-100', '100-500', '>500'])

# 归一化(0~1),用于气泡大小、颜色深浅
df['s_norm'] = (df['sales'] - df['sales'].min()) / (df['sales'].max() - df['sales'].min())
4.2.3

宽表与长表

宽表:一行一个对象,多列是不同指标;长表:一行一个"对象+指标+值"。多数图表库(seaborn、pyecharts 多系列)更适长表。

PYTHON
# 宽表 → 长表
long = df.melt(id_vars=['province'], value_vars=['2024', '2025'],
               var_name='year', value_name='sales')

# 长表 → 宽表
wide = long.pivot_table(index='province', columns='year', values='sales')

💡 判断标准:要画的系列在列名里 → 需要转长表;要画的系列在行里 → 需要转宽表。

本章小结

本章解决"图画不出来或画出来对不上"的根源问题:先识别缺失、异常、重复、口径与单位五类问题,再用填充/箱线图规则/去重/统一口径处理;随后讲分组聚合、分箱、归一化三个高频转换,最后讲清宽表与长表的区别与互转方法。

思考与练习 先自己做,再点开答案

01

销售额有少量极端值,画柱状图时把其它省份都压扁了,怎么处理?

查看参考答案

先核对是否为录入错误;确认是真实业务极值后有两种做法:① 改用对数刻度(并在轴上明确标注);② 拆成"Top N + 其它"合并展示。不要直接删掉真实数据。

02

什么情况下需要把宽表转成长表?

查看参考答案

当要画的多个系列存放在多个列里时(如 2024 列、2025 列),绘图库通常要求"系列"作为一列的取值,就需要 melt 成长表。

03

两张图的指标名称一样但数值差很多,可能是什么原因?

查看参考答案

口径不一致:统计范围(含税/不含税)、时间窗口(自然月/滚动 30 天)、去重规则(按用户/按订单)不同。必须先统一口径,并在图注中写清楚。