大家好,我是你们的小帅学长。
做数据分析,你一定遇到过这样的场景:
箱线图里蹦出几个“离群点”
散点图里出现几个“飞出去的点”
统计结果被少数极端值拉偏
很多人的第一反应是:删掉。
但我要提醒你一句,在科研里,异常值不应该先删除,而应该先“表达”。
因为,它可能是数据错误;可能是极端但真实的现象;甚至可能是你论文最重要的发现。
这一篇,我们来讲一下:异常值该怎么“画”,而不是怎么“删”。
01.异常值到底是什么?
在统计意义上,常见定义是:
小于 Q1 − 1.5×IQR
大于 Q3 + 1.5×IQR
但注意,这是统计异常,不是错误数据。
换句话说:
outlier ≠ error
outlier = “不常见”
02.为什么不要一开始就删除异常值?
如果你在分析前就删除异常值,你可能已经删除了结论。
原因有三点:
1.异常值可能代表重要机制
例如:极端气候
极端用户行为
极端实验结果
2.删除会改变分布
均值会变化
方差会变小
模型可能过拟合“干净数据”
3.审稿人会问
“你为什么删这些点?”
如果你无法解释,你的结果可信度会下降。
03.异常值的正确流程
“标准流程”是 先可视化 → 再判断 → 再处理 → 再解释
而不是,先删除 → 再分析
04.异常值怎么可视化?
1.箱线图(最基础)
优点:自动标出异常值、快速识别离群点
缺点:看不到具体分布结构
2.散点图(最直观)
优点:每个异常点都能看到、可以结合时间/空间
缺点:数据多时会遮挡
3.雨云图(最完整)
KDE(形状)
箱线(结构)
散点(个体)
4.突出异常点
核心思路:正常点 vs 异常点,用不同视觉编码
例如:
正常点:浅色
异常点:深色 / 边框 / 放大
05.论文级异常值可视化代码
这是一段可以直接使用的代码:
import osimport numpy as npimport matplotlib as mplimport matplotlib.pyplot as pltfrom matplotlib import font_manager as fmwin_fonts = r"C:\Windows\Fonts"for p in [ os.path.join(win_fonts, "times.ttf"), os.path.join(win_fonts, "timesbd.ttf"), os.path.join(win_fonts, "timesi.ttf"), os.path.join(win_fonts, "simsun.ttc"),]: if os.path.exists(p): try: fm.fontManager.addfont(p) except Exception: passmpl.rcParams["font.family"] = ["Times New Roman", "SimSun"]mpl.rcParams["axes.unicode_minus"] = FalseOUT_DIR = r"D:\py_figs"os.makedirs(OUT_DIR, exist_ok=True)np.random.seed(42)data = np.random.normal(0.6, 0.08, 200)data = np.concatenate([data, [0.2, 0.25, 0.95]])Q1 = np.percentile(data, 25)Q3 = np.percentile(data, 75)IQR = Q3 - Q1lower = Q1 - 1.5 * IQRupper = Q3 + 1.5 * IQRnormal = data[(data >= lower) & (data <= upper)]outliers = data[(data < lower) | (data > upper)]fig, ax = plt.subplots(figsize=(6,4))ax.scatter( np.zeros_like(normal), normal, color="#4C78A8", alpha=0.6, label="Normal / 正常值")ax.scatter( np.zeros_like(outliers), outliers, color="red", s=60, edgecolor="black", label="Outliers / 异常值")ax.boxplot(data, positions=[0], widths=0.2)ax.set_xticks([0])ax.set_xticklabels(["Sample / 样本"])ax.set_ylabel("Value / 数值")ax.set_title("Outlier Visualization / 异常值可视化")ax.legend(frameon=False)out_path = os.path.join(OUT_DIR, "outlier_visualization.jpg")fig.savefig(out_path, dpi=300, bbox_inches="tight")plt.close()print("Saved:", out_path)

06.异常值处理的三种策略
1.保留并解释(推荐)
用于真实极端现象。
2.单独建模
如 robust regression。
3.删除(需说明理由)
比如,设备错误、数据录入错误等。
异常值不是问题,忽略异常值才是问题。在删除异常值之前,先把它画出来,因为它可能正是你数据里最有价值的部分。
前面我们讲的都是分布类图;接下来,我们要进入关系类图表。要写的第一篇就是最基础也是最重要的《散点图基础模板》。
你会遇到一个经典问题:点太多 → 全挤在一起;点太少 → 信息不够。
下一篇,我会教你,如何用透明度解决遮挡?如何让散点图“又清楚又好看”?一套可以直接用于论文的模板。
——期待你的关注——
往期内容:
用Python做科研级画图——雨云图
用Python做科研级画图——小提琴图
用Python做科研级画图——箱线图(解释统计含义)
用Python做科研级画图——KDE密度
用Python做科研级画图——哑铃图
用Python做科研级画图——工具选型:Matplotlib、Seaborn、Plotly、Altair怎么选