Python / Pandas - 根据列值选择异常值

时间:2017-12-18 16:53:51

标签: python pandas

我有这个df:

os.eniviron

我想:

a)检查是否有相同的代码,列中的所有值" unit"是相同的

b)如果有一个"单位"这是不同的,指出哪一年是不同的。这可能仅适用于相同的代码出现在2行以上的情况(如果它在一行或两行中我们可以跟踪"不同的一行")

因此,作为示例中此df的输出,我们应该得到这个:

                 code    year             unit
0       3374312000153    2010              reg 
1       3374312000153    2009              reg
2      48300560000198    2014                k
3      48300560000198    2013                k
4      48300560000198    2012                k
5      48300560000198    2011                k
6      48300560000198    2015              reg
7      48300560000198    2016                k
8       7350260000136    2013                k
9       7350260000136    2012                k
...

有人可以提供帮助吗?

3 个答案:

答案 0 :(得分:2)

如果您将结果作为元组列表正常,那么这是一个涉及groupby的解决方案。

g = df.groupby('code')

i = g.unit.size()
j = g.unit.nunique()   
k = g.unit.value_counts(sort=False)

k.loc[k.index.levels[0][i.gt(2) & j.ge(2)]].groupby(level=0).idxmin().tolist()
[(48300560000198, 'reg')]

<强>详情

i会找到每个组的大小 -

i

code
3374312000153     2
7350260000136     2
48300560000198    6
Name: unit, dtype: int64

j会找到每组唯一商品的数量 -

j 

code
3374312000153     1
7350260000136     1
48300560000198    2
Name: unit, dtype: int64

k存储每codeunit -

的值计数
k

code            unit
3374312000153   reg     2
7350260000136   k       2
48300560000198  k       5
                reg     1
Name: unit, dtype: int64

i.gt(2) & j.ge(2)索引您正在寻找的条件 -

code
3374312000153     False
7350260000136     False
48300560000198     True
Name: unit, dtype: bool

此掩码用于索引k,仅获取我们感兴趣的ID。从那时起,应用另一个groupbyidxmin来获取异常值。< / p>

答案 1 :(得分:0)

你可以使用nunique和count(strangly size在这里工作)的组合和transform来过滤数据帧

df['unit_nunqiue'] = df.groupby('code')['unit'].transform('nunique')
df['unit_count'] = df.groupby(['code','unit'])['year'].transform('count')
df.loc[(df['unit_nunqiue']>1)&(df['unit_count']==1)].drop(['unit_nunqiue','unit_count'], axis=1)
             code  year unit
6  48300560000198  2015  reg

答案 2 :(得分:0)

我们在这里使用value_counts

df1=df.groupby('code').unit.apply(pd.value_counts)
df1.loc[((df1.sum(level=0)>2)&(df1.groupby(level=0).count()>=2)).idxmax(),:].idxmin()
Out[43]: (48300560000198, 'reg')