熊猫:删除有限的重复项

时间:2018-02-19 06:35:53

标签: python python-2.7 pandas

所以,我有一个在运行时生成的文件。该文件的示例如下所示:

ID,Class_id,Column_A,Column_B,Column_C,Column_D,Mask
1,987,vermont,CA,450,liase,2
2,456,WB,cloo,452,var,1
3,987,CA,Cp,1000000,liase,2
4,456,SA,Cap,98376,clop,1
5,765,IN,clas,543,king,2
6,987,SA,CLA,200,loop,2
7,456,BEG,loop,876,var,1

如您所见,存在Class_id的重复元素。此外,Mask指定文件中可以存在的最大重复元素数。

我尝试做的是逐个删除重复元素的最后一次出现,直到重复记录的数量与其Mask值相同为止。

如果是上述文件,

Class_id的987次发生了3次。它的Mask值为2.因此它最多只能发生2次。所以我需要删除987的最后一次出现,这是第6条记录。文件中记录的顺序与此无关。

我试图获得的输出是这样的:

ID,Class_id,Column_A,Column_B,Column_C,Column_D,Mask
1,987,vermont,CA,450,liase,2
3,987,CA,Cp,1000000,liase,2
2,456,WB,cloo,452,var,5
5,765,IN,clas,543,king,2

我在这个网站上搜索过,但却无法找到可行的解决方案。这些是我引用的网站;

Pandas: remove reverse duplicates from dataframe Find Duplicates limited to multiple ranges - pandas python pandas remove duplicate columns How to conditionally remove duplicates from a pandas dataframe Drop all duplicate rows in Python Pandas

我注意到Python有一个drop_duplicates函数。 Nut如何限制要删除的重复数量?

请有人帮助新手。感谢。

3 个答案:

答案 0 :(得分:1)

使用cumcount解决多余行的问题。使用pd.factorize + np.bincount过滤掉行数少于Mask

的行
mask = df.Mask.values
f, u = pd.factorize(df.Class_id.values)

cond1 = df.groupby('Class_id').cumcount().lt(mask)
cond2 = np.bincount(f)[f] >= mask

df[cond1 & cond2]

   ID  Class_id Column_A Column_B  Column_C Column_D  Mask
0   1       987  vermont       CA       450    liase     2
1   2       456       WB     cloo       452      var     1
2   3       987       CA       Cp   1000000    liase     2

您会注意到这是 OP具有的所需输出。该输出与 EQUAL 的行数与Mask列中的值不一致。

使用transform('size')代替pd.factorize来消除计数太小的行的另一种方法。

g = df.groupby('Class_id')

mask = df.Mask.values
cond1 = g.cumcount().lt(mask)
cond2 = g.ID.transform('size').ge(mask)

df[cond1 & cond2]

   ID  Class_id Column_A Column_B  Column_C Column_D  Mask
0   1       987  vermont       CA       450    liase     2
1   2       456       WB     cloo       452      var     1
2   3       987       CA       Cp   1000000    liase     2

答案 1 :(得分:1)

使用boolean indexing屏蔽,SeriesMask<cumcountdf = df[df.groupby('Class_id').cumcount().lt(df.Mask)] print (df) ID Class_id Column_A Column_B Column_C Column_D Mask 0 1 987 vermont CA 450 liase 2 1 2 456 WB cloo 452 var 1 2 3 987 CA Cp 1000000 liase 2 4 5 765 IN clas 543 king 2 )进行比较:

print (df.groupby('Class_id').cumcount())
0    0
1    0
2    1
3    1
4    0
5    2
6    2
dtype: int64

<强>详细

{{1}}

答案 2 :(得分:0)

使用1

cumcount