Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/332.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 Pandas通过Zscore过滤每组异常_Python_Pandas - Fatal编程技术网

Python Pandas通过Zscore过滤每组异常

Python Pandas通过Zscore过滤每组异常,python,pandas,Python,Pandas,我有一个数据框,其中一列“group”可以有50个不同的值,另一列“value”是数字 例如: pd.DataFrame({'group':['a','b','c','a','a','b','a','c','c'],'value':[2,123,4,2.3,2.5,127,128,4,0.003]}) group value 0 a 2.000 1 b 123.000 2 c 4.000 3 a 2.300 4 a 2.500 5 b 127

我有一个数据框,其中一列“group”可以有50个不同的值,另一列“value”是数字

例如:

pd.DataFrame({'group':['a','b','c','a','a','b','a','c','c'],'value':[2,123,4,2.3,2.5,127,128,4,0.003]})

group   value
0   a   2.000
1   b   123.000
2   c   4.000
3   a   2.300
4   a   2.500
5   b   127.000
6   a   128.000
7   c   4.000
8   c   0.003
我想从数据框中删除组中异常的值,例如abs(zscore)>3或类似的值。在本例中,值a,128将被删除,因为这对于a组是异常的,值c,0.003也将被删除。123和127是正常的,因为他们的组是“b”

输出应类似于(带有z分数列):

这样做的有效方法是什么


谢谢

为z分数创建一列,按特定组分组:

df['z_score'] = df.groupby('group')['value'].apply(lambda x: (x - x.mean())/x.std())
根据您的阈值筛选df:

df[abs(df['z_score']) > 3]

这是每组的绝对z分数

df.groupby('group').value.transform(lambda x: (x - x.mean()) / x.std()).abs()

0    0.504239
1    0.707107
2    0.577350
3    0.499467
4    0.496286
5    0.707107
6    1.499992
7    0.577350
8    1.154701
Name: value, dtype: float64
不幸的是,数据集太小,128所起的作用比你想象的要大。它的z分数只有1.5

我建议计算一个数据点相对于其他所有数据点的统计矩的z分数

这里有一个函数可以做到这一点。请注意,我在小组中至少需要4分才能做到这一点。如果组的长度小于4,则为整个组返回0

def _zscore(x):
    if len(x) > 3:
        v = x.values

        m = (v.sum() - v) / (v.size - 1)

        vm = v - m[:, None]
        np.fill_diagonal(vm, 0)

        s = ((vm ** 2).sum(1) / (v.size - 2)) ** .5

        return (v - m) / s
    else:
        return np.zeros_like(x)
现在如果我们
groupby
transform

df.groupby('group').value.transform(_zscore)

0     -0.582866
1      0.000000
2      0.000000
3     -0.576658
4     -0.572532
5      0.000000
6    499.613605
7      0.000000
8      0.000000
Name: value, dtype: float64
我们可以清楚地看到,
128
得到了
\uzscore
499
。通过一个简单的假设检验,我们可以安全地得出结论,
128
不太可能来自与组内其他数据相同的分布

我们可以像这样过滤它:

df[df.groupby('group').value.transform(_zscore) <= 3]

  group    value
0     a    2.000
1     b  123.000
2     c    4.000
3     a    2.300
4     a    2.500
5     b  127.000
7     c    4.000
8     c    0.003

df[df.groupby('group').value.transform(_zscore)要计算每个组的zscore吗?请提供所需输出的具体证据。我要每个组的zscore值,然后过滤zscore超出某个阈值的记录。Tx.z分数需要假设检验。你的零假设是什么?
df[df.groupby('group').value.transform(_zscore) <= 3]

  group    value
0     a    2.000
1     b  123.000
2     c    4.000
3     a    2.300
4     a    2.500
5     b  127.000
7     c    4.000
8     c    0.003