从这个问题开始为基础。
Python Pandas: remove entries based on the number of occurrences
data = pandas.DataFrame(
{'pid' : [1,1,1,2,2,3,3,3],
'tag' : [23,45,62,24,45,34,25,62],
})
# pid tag
# 0 1 23
# 1 1 45
# 2 1 62
# 3 2 24
# 4 2 45
# 5 3 34
# 6 3 25
# 7 3 62
g = data.groupby('tag')
g.filter(lambda x: len(x) > 1) # filters out lengths > 1.
# pid tag
# 1 1 45
# 2 1 62
# 4 2 45
# 7 3 62
#This would create a new object g:
g = g.filter(lambda x: len(x) > 1) #where g is now a dataframe.
我想知道是否有办法过滤掉'群组'删除
它们来自原始对象g
。并且,它比从过滤的groupby创建新的groupby
对象更快。
答案 0 :(得分:1)
只有很多方法可以解决这个问题。我的回答包括4个解决方案我相信,还有其他方法。也许其他一些答案会提供更好的方法。
解决方案#1:
data = data.groupby('tag').filter(lambda x: len(x) > 1)
pid tag
1 1 45
2 1 62
4 2 45
7 3 62
解决方案#2:
data['count'] = data.groupby(['tag']).transform('count')
data.loc[data['count'] == 2]
pid tag count
1 1 45 2
2 1 62 2
4 2 45 2
7 3 62 2
解决方案#3:
如果您想要删除行,可以使用.index.tolist()
然后使用drop()
。
data['count'] = data.groupby(['tag']).transform('count')
data.drop(data[data['count'] != 2].index.tolist())
pid tag count
1 1 45 2
2 1 62 2
4 2 45 2
7 3 62 2
解决方案#4:
data['count'] = data.groupby(['tag']).transform('count')
g = data.groupby('count')
data.loc[g.groups[2],('tag','pid')]
tag pid
1 45 1
2 62 1
4 45 2
7 62 3
答案 1 :(得分:1)
有几种选择(你的选择在底部):
第一个是inplace
,我尽可能快。它比你的解决方案快一点,但不是因为丢弃了行。我可以通过第二个选项获得更好的性能,但这并没有改变。
%%timeit
data = pd.DataFrame(
{'pid' : [1,1,1,2,2,3,3,3],
'tag' : [23,45,62,24,45,34,25,62],
})
mask = ~data.duplicated(subset=['tag'], keep=False)
data.drop(mask[mask].index, inplace=True)
data
1000 loops, best of 3: 1.16 ms per loop
%%timeit
data = pd.DataFrame(
{'pid' : [1,1,1,2,2,3,3,3],
'tag' : [23,45,62,24,45,34,25,62],
})
data = data.loc[data.duplicated(subset=['tag'], keep=False)]
data
1000 loops, best of 3: 719 µs per loop
%%timeit
data = pd.DataFrame(
{'pid' : [1,1,1,2,2,3,3,3],
'tag' : [23,45,62,24,45,34,25,62],
})
g = data.groupby('tag')
g = g.filter(lambda x: len(x) > 1)
g
1000 loops, best of 3: 1.55 ms per loop