带有lambda的熊猫groupby在列表中

时间:2018-09-10 22:40:49

标签: python pandas list lambda pandas-groupby

我有以下数据框

df = pd.DataFrame({'ItemType': ['Red', 'White', 'Red', 'Blue', 'White', 'White', 'White', 'Green'], 
               'ItemPrice': [10, 11, 12, 13, 14, 15, 16, 17], 
               'ItemID': ['A', 'A', 'B', 'B', 'C', 'C', 'D', 'D']})

我想获取具有ID的记录(行),这些记录的ID仅以DataFrame的形式包含“白色” ItemType

我尝试了以下解决方案:

types = ['Red','Blue','Green']

~df.groupby('ItemID')['ItemType'].any().apply(lambda u: u in(types))

但这给了我一个不正确的结果(D应该为False),并且是一系列的结果。

A False
B False
C True
D True

谢谢!

2 个答案:

答案 0 :(得分:2)

您应避免在此处使用 apply ,因为通常速度很慢。相反,请在flag之前分配groupby列,然后使用all断言types中没有任何组值:

df.assign(flag=~df.ItemType.isin(types)).groupby('ItemID').flag.all()

ItemID
A    False
B    False
C     True
D    False
Name: flag, dtype: bool

但是,仅是为了演示操作的逻辑,并说明您的方法的不正确之处,以下是使用apply的有效版本:

~df.groupby('ItemID').ItemType.apply(lambda x: any(i in types for i in x))

在使用any之前,您需要在Lambda中使用apply ,而不是在Series上。


要访问满足此条件的行,可以使用transform

df[df.assign(flag=~df.ItemType.isin(types)).groupby('ItemID').flag.transform('all')]

  ItemType  ItemPrice ItemID
4    White         14      C
5    White         15      C

答案 1 :(得分:1)

另一种方法是计算非白色ItemID值的数组。然后过滤数据框:

non_whites = df.loc[df['ItemType'].ne('White'), 'ItemID'].unique()

res = df[~df['ItemID'].isin(non_whites)]

print(res)

  ItemType  ItemPrice ItemID
4    White         14      C
5    White         15      C

您也可以使用GroupBy,但这不是绝对必要的。