Pandas groupby与lambda并在列表中

问题描述 投票:2回答:2

我有以下数据框

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']})

我想获得ItemIDs的记录(行),其中只包含DataFrame形式的“White”ItemType

我试过以下解决方案:

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

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

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

A False
B False
C True
D True

谢谢!

python pandas list lambda pandas-groupby
2个回答
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))

你需要在lambda中使用any,而不是在使用apply之前使用系列。


要访问满足此条件的行,您可以使用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
投票

另一种方法是计算非白色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,但这不是绝对必要的。

© www.soinside.com 2019 - 2024. All rights reserved.