首页 文章

从matlab boxplot中删除某些异常值

提问于
浏览
0

在MATLAB中,boxplot命令可用于生成箱图 . 此函数的默认行为是晶须长度为1.5 * IQR(第75百分位数 - 第25百分位数),如果需要,此晶须长度可以更改为IQR的另一倍数 . 但是,不可能使用特定的百分位数作为胡须的限制,这是我需要的(在我的例子中是第10和第90百分位数) . 正如您将在下面的示例中看到的那样,我到目前为止已遇到问题 .

请考虑以下数据:

Box_Data_PFCA = [-3;1;2;3;4;5;5;5;6;40;45;77;7;9;1;2;3;7;7;7;10;11;11;40;30;101;110;150];
    label = ['PFOS';'PFOS';'PFOS';'PFOS';'PFOS';'PFOS';'PFOS';'PFOS';'PFOS';'PFOS';'PFOS';'PFOS';'PFOS';'PFOS';...
             'PFDA';'PFDA';'PFDA';'PFDA';'PFDA';'PFDA';'PFDA';'PFDA';'PFDA';'PFDA';'PFDA';'PFDA';'PFDA';'PFDA'];

我使用defualt matlab函数从中生成一个boxplot:

h = boxplot(Box_Data_PFCA,label)

然后我计算生成箱线图所需的百分位数:

PFOS_10=prctile([-3;1;2;3;4;5;5;5;6;40;45;77;7;9],10)
PFOS_25=prctile([-3;1;2;3;4;5;5;5;6;40;45;77;7;9],25)
PFOS_75=prctile([-3;1;2;3;4;5;5;5;6;40;45;77;7;9],75)
PFOS_90=prctile([-3;1;2;3;4;5;5;5;6;40;45;77;7;9],90)
PFDA_10=prctile([1;2;3;7;7;7;10;11;11;40;30;101;110;150],10)
PFDA_25=prctile([1;2;3;7;7;7;10;11;11;40;30;101;110;150],25)
PFDA_75=prctile([1;2;3;7;7;7;10;11;11;40;30;101;110;150],75)
PFDA_90=prctile([1;2;3;7;7;7;10;11;11;40;30;101;110;150],90)

然后我继续使用图形句柄编辑方框图(在我的情况下编辑框是无法识别的,因为25%到75%的默认设置适合我但是为了完整性我显示它):

set(h(5,1), 'YData', [PFOS_25 PFOS_75 PFOS_75 PFOS_25 PFOS_25])
set(h(1,1), 'YData', [PFOS_75 PFOS_90])
set(h(2,1), 'YData', [PFOS_10 PFOS_25])
set(h(3,1), 'YData', [PFOS_90 PFOS_90])
set(h(4,1), 'YData', [PFOS_10 PFOS_10])
set(h(5,2), 'YData', [PFDA_25 PFDA_75 PFDA_75 PFDA_25 PFDA_25])
set(h(1,2), 'YData', [PFDA_75 PFDA_90])
set(h(2,2), 'YData', [PFDA_10 PFDA_25])
set(h(3,2), 'YData', [PFDA_90 PFDA_90])
set(h(4,2), 'YData', [PFDA_10 PFDA_10])

这导致以下结果:

enter image description here

正如你所看到的,我对胡须的变化后,我的一些异常值与胡须重叠 .

我的问题是如何在我的更改后确保我的胡须内的异常值被移除(并且在我的胡须之外) . 我意识到我需要以某种方式使用'Outliers'句柄,但解决方案并没有呈现给我...因为这只是一个示例数据集,解决方案必须处理大型数据集 .

2 回答

  • 0

    因此,如果一个点小于您的最高胡须,并且大于最低胡须,您将删除它们 .

    你不能只从你的 h 变量中检查他们的位置 . 这样的事情:

    idx = find(h(6:end,1).YData<PFOS_90&h(6:end,1).YData>PFOS_10);
    h(5+idx,1)=[];
    

    [编辑]

    很高兴上面的想法为您指出了一个有效的解决方案!你的代码有点长,但非常易读 . 这也很重要 . 但也许这四条线做同样的工作?

    idx = find(h(7,1).YData<PFOS_90&h(7,1).YData>PFOS_10);
    h(7,1).YData(idx)=[];h(7,1).XData(idx)=[];
    idx = find(h(7,2).YData<PFOS_90&h(7,2).YData>PFOS_10);
    h(7,2).YData(idx)=[];h(7,2).XData(idx)=[];
    

    如果你有很多要删除的点,你需要检查的不仅仅是(7,1)和(7,2)吗?在这种情况下,放置一个循环 for i = 1:size(h,2)

    [/编辑]

  • 1

    在@Gelliants提示后,我设法找到了解决方案 . 它不漂亮,毫无疑问会更精致,但它的工作原理 . 我将以下代码行添加到我的问题中发布的代码:

    a = get(h(7,1), 'YData')
    b = get(h(7,1), 'XData')
    idx = find(a<PFOS_90&a>PFOS_10)
    a(idx)=[]
    b(idx)=[]
    set(h(7,1), 'YData', a, 'XData', b)
    e = get(h(7,2), 'YData')
    f = get(h(7,2), 'XData')
    idx = find(e<PFDA_90&e>PFDA_10)
    e(idx)=[]
    f(idx)=[]
    set(h(7,2), 'YData', e, 'XData', f)
    

    这导致下面的图可以与问题中的原始图进行比较 . 欢迎提供有关如何优化我的解决方案的任何提示!

    enter image description here

相关问题