熊猫:使用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,但是我发现这是一个比更为安全的选择,在某些情况下,这对我来说很麻烦。