Python中的调整箱线图

a2mppw5e  于 2023-05-16  发布在  Python
关注(0)|答案(2)|浏览(180)

在我的论文中,我试图识别数据集中的异常值。该数据集是从一个真实的过程环境中的一个变量的160000倍。然而,在这种环境中,可能存在不是来自过程本身的实际数据而只是垃圾数据的测量。我想用我很少的文献帮助来过滤它们,而不是只有“Maven意见”。
现在我已经读到了IQR方法,当处理像正态分布这样的对称分布时,它可以看到可能的离群值是否存在。然而,我的数据集是右偏的,通过分布拟合,反伽玛和对数正态分布是最好的拟合。
因此,在我搜索非对称分布的方法时,我在cross-validated上发现了这个主题,其中user 603的答案特别有趣:Is there a boxplot variant for Poisson distributed data?
在user 603的回答中,他指出调整后的箱线图有助于识别数据集中可能的异常值,R和Matlab都有相应的函数
(有一个𝚁R实现(𝚛𝚘𝚋𝚞𝚜𝚝𝚋𝚊𝚜𝚎::𝚊𝚍𝚓𝚋𝚘𝚡()robustbase::adjbox())以及matlab实现(在一个名为libra的库中𝚕𝚒𝚋𝚛𝚊)
我想知道Python中是否有这样的函数。或者有没有一种方法可以用python计算medcouple(见user 603的回答)?
我真的很想看看我的数据调整后的箱线图是什么。

jjjwad0x

jjjwad0x1#

在模块statmodels.stats.stattools中有一个函数medcouple(),它是调整后箱线图中使用的偏度的度量。
enter link description here
使用此变量,您可以计算定义离群值的区间。

bvk5enib

bvk5enib2#

下面是一个可能的解决方案,遵循Christophe's answer并解决@banderlog013的评论。
1.查找识别异常值和绘制箱线图所需的参数:

import statsmodels.api as sm
import datetime
import seaborn as sns
def adjusted_boxplot_params(data:pd.Series):
    ''' 
    Returns:
    @outlier_range_lower: lower bound of normal expected values. Everything below are outlier candidates.
    @outlier_range_upper: upper bound of normal expected values. Above are outlier candidates.
    @whis: (lowWhis,highWhis) whis parameter for the boxplot method, in a form (low_percentage, high_percentage), as expected by pyplot.boxplot().
    '''

    q1 = data.quantile(0.25)
    q3 = data.quantile(0.75)

    # Calculate the interquartile range
    iqr = q3 - q1
    #calculate medcouple
    y = np.asarray(data, dtype=np.double) 
    MC = sm.stats.stattools.medcouple(y) 

    # Define the outlier range 
    if (MC>0):
        outlier_range_lower = q1 - 1.5 * np.exp(-4*MC) * iqr
        outlier_range_upper = q3 + 1.5 * np.exp(3*MC)  * iqr
    else:
        outlier_range_lower = q1 - 1.5 * np.exp(-3*MC) * iqr
        outlier_range_upper = q3 + 1.5 * np.exp(4*MC)  * iqr

    whis = np.interp([outlier_range_lower, outlier_range_upper], np.sort(data), np.linspace(0, 1, data.size)) * 100 #Ref: https://stackoverflow.com/a/65390045/7745170

    return outlier_range_lower, outlier_range_upper, whis

1.从dataframe列中选择离群值,并根据需要绘制调整后的箱线图:

def select_outliers_adjusted_boxplot(df, col_name:str,show_plot=False): 
    ''' selects rows in the dataframe df which coll_name falls out of bounds [min,max]
    @df: dataframe 
    @col_name: column to analyze 
    Returns:
    @otuliers: df with selected rows from input df.
    '''

    outlier_range_lower, outlier_range_upper, whis = adjusted_boxplot_params(df[col_name])
    # Select the rows where the duration is outside the outlier range
    outliers = df[(df[col_name] < outlier_range_lower) |
                  (df[col_name] > outlier_range_upper)]

    if show_plot==True:
        plot = sns.boxplot(x=df[col_name,whis=whis) nacrtaj_boxplot_durations(df[col_name], plot_title,whis)
        plt.show(plot2)

    # Return the DataFrame containing the outliers
    return outliers

相关问题