熊猫:使用groupby和函数过滤DataFrame
问题内容:
使用Python 3.3和Pandas 0.10
我有一个通过串联多个CSV文件构建的DataFrame。首先,我过滤掉“名称”列中包含特定字符串的所有值。结果看起来像这样(为简洁起见,它缩短了,实际上有更多列):
Name ID
'A' 1
'B' 2
'C' 3
'C' 3
'E' 4
'F' 4
... ...
现在,我的问题是我想删除“重复”值的特殊情况。我要删除所有ID重复项(实际上是整行),其中映射到此ID的相应Name值 不
相似。在上面的示例中,我想保留ID为1、2和3的行。在ID = 4的情况下,Name值不相等,我想删除它们。
我尝试使用以下代码行(基于此处的建议:Python
Pandas:根据出现的次数删除条目
)。
码:
df[df.groupby('ID').apply(lambda g: len({x for x in g['Name']})) == 1]
但是,这给了我错误: ValueError: Item wrong length 51906 instead of 109565!
编辑:
除了apply()
尝试使用之外transform()
,我还尝试使用,但是出现了以下错误:AttributeError: 'int' object has no attribute 'ndim'
。非常感谢对为什么每个函数的错误有所不同的解释!
另外,在上面的示例中,我想保留ID = 3的所有行。
预先感谢,Matthijs
问题答案:
len
我认为您要考虑的不是每个长度,而是每个组中Name的唯一值的数量。使用nunique()
,并检查此简洁的配方以过滤组。
df[df.groupby('ID').Name.transform(lambda x: x.nunique() == 1).astype('bool')]
如果您升级到熊猫0.12,则可以filter
在组上使用新方法,这将使其更加简洁明了。
df.groupby('ID').filter(lambda x: x.Name.nunique() == 1)
一句话:当然,有时候您确实想知道小组的size
人数len
,但是我发现这是一个比更为安全的选择,在某些情况下,这对我来说很麻烦。