Pandas-按id分组并删除带阈值的副本

2024-06-28 19:33:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下数据:

userid itemid
  1       1
  1       1
  1       3
  1       4
  2       1
  2       2
  2       3

我想删除查看同一项ID超过或等于两次的用户ID。 例如,userid=1查看了itemid=1两次,因此我想删除userid=1的整个记录。但是,由于userid=2没有查看同一个项目两次,我将保持userid=2不变。

所以我希望我的数据如下:

userid itemid
  2       1
  2       2
  2       3

有人能帮我吗?

import pandas as pd    
df = pd.DataFrame({'userid':[1,1,1,1, 2,2,2],
                   'itemid':[1,1,3,4, 1,2,3] })

Tags: 数据项目用户importiddataframepandasdf
3条回答

可以使用^{}确定行级重复项,然后对“userid”执行groupby以确定“userid”级重复项,然后相应地删除。

无阈值下降:

df = df[~df.duplicated(['userid', 'itemid']).groupby(df['userid']).transform('any')]

要降低阈值,请在duplicated中使用keep=False,并对布尔列求和,然后与阈值进行比较。例如,阈值为3时:

df = df[~df.duplicated(['userid', 'itemid'], keep=False).groupby(df['userid']).transform('sum').ge(3)]

无阈值的结果输出:

   userid  itemid
4       2       1
5       2       2
6       2       3

按用户和项对数据帧进行分组:

views = df.groupby(['userid','itemid'])['itemid'].count()
#userid  itemid
#1       1         2 <=== The offending row
#        3         1
#        4         1
#2       1         1
#        2         1
#        3         1
#Name: dummy, dtype: int64

找出只有一次看到任何物品的人:

THRESHOLD = 2
viewed = ~(views.unstack() >= THRESHOLD).any(axis=1)
#userid
#1    False
#2     True
#dtype: bool

合并结果并保留“好”行:

combined = df.merge(pd.DataFrame(viewed).reset_index())
combined[combined[0]][['userid','itemid']]
#   userid  itemid
#4       2       1
#5       2       2
#6       2       3

^{}

是为这个做的。可以传递一个返回布尔值的函数,该布尔值确定组是否通过了筛选器。

filtervalue_counts
最普遍和直观的

df.groupby('userid').filter(lambda x: x.itemid.value_counts().max() < 2)

filteris_unique
查找n < 2时的特殊情况

df.groupby('userid').filter(lambda x: x.itemid.is_unique)

   userid  itemid
4       2       1
5       2       2
6       2       3

相关问题 更多 >