Python:根据出现的次数删除条目
我正在尝试从数据帧中删除出现次数少于100次的条目。 数据框Python:根据出现的次数删除条目,python,numpy,python-2.7,pandas,Python,Numpy,Python 2.7,Pandas,我正在尝试从数据帧中删除出现次数少于100次的条目。 数据框data如下所示: pid tag 1 23 1 45 1 62 2 24 2 45 3 34 3 25 3 62 bytag = data.groupby('tag').aggregate(np.count_nonzero) 现在我按如下方式计算标记出现的次数: pid tag 1 23 1 45 1 62 2
data
如下所示:
pid tag
1 23
1 45
1 62
2 24
2 45
3 34
3 25
3 62
bytag = data.groupby('tag').aggregate(np.count_nonzero)
现在我按如下方式计算标记出现的次数:
pid tag
1 23
1 45
1 62
2 24
2 45
3 34
3 25
3 62
bytag = data.groupby('tag').aggregate(np.count_nonzero)
但是我不知道如何删除那些低计数的条目
df = pd.DataFrame([(1, 2), (1, 3), (1, 4), (2, 1),(2,2,)], columns=['col1', 'col2'])
In [36]: df
Out[36]:
col1 col2
0 1 2
1 1 3
2 1 4
3 2 1
4 2 2
gp = df.groupby('col1').aggregate(np.count_nonzero)
In [38]: gp
Out[38]:
col2
col1
1 3
2 2
让我们到达计数大于2的位置
tf = gp[gp.col2 > 2].reset_index()
df[df.col1 == tf.col1]
Out[41]:
col1 col2
0 1 2
1 1 3
2 1 4
编辑:感谢@WesMcKinney以更直接的方式展示:
data[data.groupby('tag').pid.transform(len) > 1]
屈服
pid tag
1 1 45
2 1 62
4 2 45
7 3 62
groupby对象在0.12中新增了一个方法,允许您执行以下类型的操作:
In [11]: g = data.groupby('tag')
In [12]: g.filter(lambda x: len(x) > 1) # pandas 0.13.1
Out[12]:
pid tag
1 1 45
2 1 62
4 2 45
7 3 62
函数(filter的第一个参数)应用于每个组(子帧),结果包括属于组的原始数据帧的元素,这些组的计算结果为True
注:,这是在0.13+中固定的:
In [21]: g.filter(lambda x: len(x) > 1) # pandas 0.12
Out[21]:
pid tag
1 1 45
4 2 45
2 1 62
7 3 62
以下是此处发布的两个解决方案的一些运行时间,以及一个没有运行的(使用
value\u counts()
)运行时间,比其他解决方案快得多:
创建数据:
输出:
171个用户在数据集中只出现一次
使用几种不同的方法删除只有一个条目的用户。这些都在Jupyter笔记本中的单独单元格中运行:
这些成果如下:
现在我有了主意。另一种方法是连接这些数据帧,它将删除不匹配的条目,然后我可以删除count列。jep这将起作用2。我通常只使用一个掩码,然后选择我需要的列一行:data[data.groupby('tag').pid.transform(len)>1]我们现在有了这个方法。如果我有另一列写着“userid”,该怎么办。我只想选择那些数据,其中pid有100多个和条目,同时uid有100多个条目。我试过了&只是分组,但似乎不起作用。reviews\u imp\u pr=reviews\u imp[(reviews\u imp.groupby('author')['score'].count()>50)和(reviews\u imp.groupby('product')['score'].count()>50)]我想知道结果的顺序不一致是否是有意的……感谢回到这个问题来宣扬过滤的福音。重新排序是一个已知的问题,我应该将其包含在文档中。如果设置
dropna=False
,则会保持顺序。如果没有,则分组可能会被洗牌。使用它们会花费时间,所以我把它留给了用户,这是一个有争议的选择。@DanAllan同样,如果有重复/无序的索引,将它们重新排序可能不是件小事。啊哈,现在你可以做:g.filter(lambda x:len(x)>1,dropna=False)。dropna()
来维持秩序。@DanAllan哦,不,你不能。。。因为重新索引不适用于重复。所以过滤器不起作用。请注意,也不要变换。请考虑把这个问题作为可接受的答案。这是更简单的,是正确的方法。请考虑改变接受的答案(过滤方法更简单:))这肯定是可接受的答案。使用value_counts()的方法要比其他两种方法快得多,特别是对于具有大量组的数据集。在3000万数据中,该方法非常快。非常感谢。
%%timeit
df.groupby(by='uid').filter(lambda x: len(x) > 1)
%%timeit
df[df.groupby('uid').uid.transform(len) > 1]
%%timeit
vc = df.uid.value_counts()
df[df.uid.isin(vc.index[vc.values > 1])].uid.value_counts()
10 loops, best of 3: 46.2 ms per loop
10 loops, best of 3: 30.1 ms per loop
1000 loops, best of 3: 1.27 ms per loop