You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Seaborn 0.7.1箱线图四分位数疑问:Q1结果与预期不符

为什么Seaborn 0.7.1的箱线图Q1和手动计算的不一样?

这其实是四分位数计算方法的差异导致的,你手动用的是经典的Tukey四分位数法,但Seaborn 0.7.1底层依赖的计算逻辑和它不同。

先拆解一下细节:

  • 你的数据排序后是:[2, 4, 5, 5, 8, 8, 9](共7个元素)
  • 你手动计算的逻辑:
    1. 中位数Q2是第4个元素:5
    2. Q1取前半部分([2,4,5])的中位数:4
    3. Q3取后半部分([8,8,9])的中位数:8

但Seaborn 0.7.1在绘制箱线图时,底层调用的是Matplotlib的boxplot函数,而当时的Matplotlib是用numpy.percentile来计算分位数,默认采用线性插值的方式。具体计算过程是:

  1. 25%分位数的位置公式为:(n-1)*p,这里n=7,p=0.25,得到(7-1)*0.25=1.5
  2. 这个位置对应数组中索引1(值4)和索引2(值5)之间的位置,用线性插值计算:4 + (5-4)*0.5 = 4.5,这就是你图里看到的Q1。

你可以用下面的代码验证这个结果:

import numpy as np
arr = np.array([2, 4, 5, 5, 8, 8, 9])
print(np.percentile(arr, 25))  # 输出:4.5

如果想要得到和手动计算一致的箱线图,你可以手动计算分位数后用Matplotlib直接绘制,或者使用scipy.stats里的分位数计算方法(对应Tukey的逻辑):

import matplotlib.pyplot as plt
from scipy.stats.mstats import mquantiles

arr = np.array([2,4,5,5,8,8,9])
# 用Tukey方法计算分位数
q1, q2, q3 = mquantiles(arr, [0.25, 0.5, 0.75], alphap=0.5, betap=0.5)

# 手动绘制符合预期的箱线图
fig, ax = plt.subplots()
box = ax.boxplot(arr, showfliers=False)
# 调整箱子的关键位置为手动计算的分位数
box['boxes'][0].set_ydata([q1, q1, q3, q3, q1])
box['medians'][0].set_ydata([q2, q2])
box['caps'][0].set_ydata([arr.min(), arr.min()])
box['caps'][1].set_ydata([arr.max(), arr.max()])
box['whiskers'][0].set_ydata([arr.min(), q1])
box['whiskers'][1].set_ydata([q3, arr.max()])

plt.show()

简单来说,不同统计工具对四分位数的计算没有统一标准,常见的就有五六种方法,Seaborn旧版本用的是Numpy默认的线性插值法,和你手动的Tukey法逻辑不同,所以结果出现了差异。

内容的提问来源于stack exchange,提问作者Vishesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:56:51