Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 熊猫-用groupby平均值替换异常值_Python_Pandas - Fatal编程技术网

Python 熊猫-用groupby平均值替换异常值

Python 熊猫-用groupby平均值替换异常值,python,pandas,Python,Pandas,我有一个pandas数据框架,我想把它分成几个组,计算平均值和标准偏差,然后用组的平均值替换所有的异常值。如果偏离组平均值超过3个标准差,则定义为异常值 df = pandas.DataFrame({'a': ['A','A','A','B','B','B','B'], 'b': [1.1,1.2,1.1,3.3,3.4,3.3,100.0]}) 我认为以下方法可行: df.groupby('a')['b'].transform(lambda x: x[i] if np.abs(x[i]-x.

我有一个pandas数据框架,我想把它分成几个组,计算平均值和标准偏差,然后用组的平均值替换所有的异常值。如果偏离组平均值超过3个标准差,则定义为异常值

df = pandas.DataFrame({'a': ['A','A','A','B','B','B','B'], 'b': [1.1,1.2,1.1,3.3,3.4,3.3,100.0]})
我认为以下方法可行:

df.groupby('a')['b'].transform(lambda x: x[i] if np.abs(x[i]-x.mean())<=(3*x.std()) else x.mean() for i in range(0,len(x)))
但我得到了一个不同的错误:

关键错误:0

最后,我求助于创建一个单独的专栏:

df['c'] = [df.groupby('a')['b'].transform(mean) if df.groupby('a')['b'].transform(lambda x: (x - x.mean()) / x.std()) > 3 else df['b']] 
但这也没有奏效:

ValueError:序列的真值不明确。使用a.empty、a.bool()、a.item()、a.any()或a.all()

非常感谢您的建议。

试试以下方法:

def replace(group):
    mean, std = group.mean(), group.std()
    outliers = (group - mean).abs() > 3*std
    group[outliers] = mean        # or "group[~outliers].mean()"
    return group

df.groupby('a').transform(replace)

注意:如果您想消除上一组中的100个,您可以用
1*std
替换
3*std
。该组中的标准偏差为48.33,因此将其包括在结果中。

首先去除异常值,然后计算组平均值以进行替换更为合适。如果用异常值计算替换平均值,则平均值会受到异常值的影响,希望这会有所帮助:

步骤1,删除异常值(参考):

第2步,替换异常值(参考elyase):


但这难道不意味着会受到异常值的影响吗?
df['c'] = [df.groupby('a')['b'].transform(mean) if df.groupby('a')['b'].transform(lambda x: (x - x.mean()) / x.std()) > 3 else df['b']] 
def replace(group):
    mean, std = group.mean(), group.std()
    outliers = (group - mean).abs() > 3*std
    group[outliers] = mean        # or "group[~outliers].mean()"
    return group

df.groupby('a').transform(replace)
def is_outlier(s):
    lower_limit = s.mean() - (s.std() * 3)
    upper_limit = s.mean() + (s.std() * 3)
    return ~s.between(lower_limit, upper_limit)

df = df[~df.groupby('a')['count'].apply(is_outlier)]
def replace(group):
    mean, std = group.mean(), group.std()
    outliers = (group - mean).abs() > 3*std
    group[outliers] = mean        # or "group[~outliers].mean()"
    return group

df.groupby('a').transform(replace)