Matplotlib 中的 Tukey Boxplots - 代码中的异常值逻辑?
Tukey Boxplots in Matplotlib - outlier logic in the code?
在阅读 a related question in Whosebug, I saw the code used in matplotlib to compute the wiskers positions and detect outliers 的答案时:
# get high extreme
iq = q3 - q1
hi_val = q3 + whis * iq
wisk_hi = np.compress(d <= hi_val, d)
if len(wisk_hi) == 0 or np.max(wisk_hi) < q3:
wisk_hi = q3
else:
wisk_hi = max(wisk_hi)
现在,else
部分非常有意义 - 根据 Tukey boxplots 的规范,我们在上四分位数的 1.5 IQR 范围内找到最高数据。确实,那是 max(wish_hi)
- 最大的数据条目 低于 Q3+1.5*IQR
.
但是 or
部分...我不明白。 if len(wisk_hi) == 0
转换为...
if we find no elements below the `hi_val` ...
这个条件如何适用? Q3 是通过在中位数上拆分数据,然后取上半部分的中位数,然后在上面加上 1.5*IQR - 怎么可能没有数据 比这个值低?
如果这是关于一个空数据集,那么 or
的第二部分也没有意义(因为没有数据,Q3 或 IQR 就没有意义)。
可能遗漏了一些明显的东西 - 求助?
四分位数间距可能有偏差。 "The upper adjacent value can be less than Q3, which forces the whisker to be drawn from Q3 into the box. The lower adjacent value can also be greater than Q1, which forces the whisker to be drawn from Q1 into the box." (source)
IQR = Q3 - Q1
下限:Q1 - 1.5 (Q3 - Q1)
上限:Q3 + 1.5 (Q3 - Q1)
查看link中的数据。
下面的示例输出(实际上是从 matplotlib 测试数据驱动的)显示了问题:
$ ipython2
Python 2.7.11 (default, Mar 31 2016, 06:18:34)
IPython 4.2.0 -- An enhanced Interactive Python.
In [1]: import numpy as np
In [2]: import matplotlib
In [3]: a=[3, 9000, 150, 88, 350, 200000, 1400, 960]
In [4]: sa=list(sorted(a))
In [5]: sa
Out[5]: [3, 88, 150, 350, 960, 1400, 9000, 200000]
In [6]: globals().update(matplotlib.cbook.boxplot_stats(a)[0])
In [7]: q3
Out[7]: 3300.0
In [8]: iqr
Out[8]: 3165.5
In [9]: q3+1.5*iqr
Out[9]: 8048.25
...所以小于q3+1.5*iqr
的最大元素是...1400!
如果代码不包含该测试,则上须线必须从 q3 (3300) 下降到 1400。
在阅读 a related question in Whosebug, I saw the code used in matplotlib to compute the wiskers positions and detect outliers 的答案时:
# get high extreme
iq = q3 - q1
hi_val = q3 + whis * iq
wisk_hi = np.compress(d <= hi_val, d)
if len(wisk_hi) == 0 or np.max(wisk_hi) < q3:
wisk_hi = q3
else:
wisk_hi = max(wisk_hi)
现在,else
部分非常有意义 - 根据 Tukey boxplots 的规范,我们在上四分位数的 1.5 IQR 范围内找到最高数据。确实,那是 max(wish_hi)
- 最大的数据条目 低于 Q3+1.5*IQR
.
但是 or
部分...我不明白。 if len(wisk_hi) == 0
转换为...
if we find no elements below the `hi_val` ...
这个条件如何适用? Q3 是通过在中位数上拆分数据,然后取上半部分的中位数,然后在上面加上 1.5*IQR - 怎么可能没有数据 比这个值低?
如果这是关于一个空数据集,那么 or
的第二部分也没有意义(因为没有数据,Q3 或 IQR 就没有意义)。
可能遗漏了一些明显的东西 - 求助?
四分位数间距可能有偏差。 "The upper adjacent value can be less than Q3, which forces the whisker to be drawn from Q3 into the box. The lower adjacent value can also be greater than Q1, which forces the whisker to be drawn from Q1 into the box." (source)
IQR = Q3 - Q1
下限:Q1 - 1.5 (Q3 - Q1)
上限:Q3 + 1.5 (Q3 - Q1)
查看link中的数据。
下面的示例输出(实际上是从 matplotlib 测试数据驱动的)显示了问题:
$ ipython2
Python 2.7.11 (default, Mar 31 2016, 06:18:34)
IPython 4.2.0 -- An enhanced Interactive Python.
In [1]: import numpy as np
In [2]: import matplotlib
In [3]: a=[3, 9000, 150, 88, 350, 200000, 1400, 960]
In [4]: sa=list(sorted(a))
In [5]: sa
Out[5]: [3, 88, 150, 350, 960, 1400, 9000, 200000]
In [6]: globals().update(matplotlib.cbook.boxplot_stats(a)[0])
In [7]: q3
Out[7]: 3300.0
In [8]: iqr
Out[8]: 3165.5
In [9]: q3+1.5*iqr
Out[9]: 8048.25
...所以小于q3+1.5*iqr
的最大元素是...1400!
如果代码不包含该测试,则上须线必须从 q3 (3300) 下降到 1400。