我有以下数据框
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
谢谢!
答案 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
,但这不是绝对必要的。