繁体   English   中英

Pandas:删除有限的重复项

[英]Pandas: Remove limited duplicates

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

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:从数据框中删除反向重复项查找重复项限于多个范围 - pandas python pandas remove duplicate columns 如何有条件地从Pandas 数据框中删除重复项 删除 Python Pandas 中的所有重复行

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

有人可以帮助这里的新手吗? 谢谢。

使用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 想要的输出。 该输出与等于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

使用boolean indexing和掩码比较Series by cumcount与列Masklt ( < ):

df = 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

使用cumcount

In [260]: df[df.groupby('Class_id').cumcount() < df['Mask']]
Out[260]:
   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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM