我有一个包含多列的数据框。
df= pd.DataFrame({
'Name': ['Peter', 'Peter', 'Peter', 'Jake', 'Jake'],
'Product' : ['A', 'B', 'C', 'A', 'B']
})
Name Product
0 Peter A
1 Peter B
2 Peter C
3 Jake A
4 Jake B
这些列包含name
和product
。
如何选择具有多个产品的name
,例如产品A
,B
和C
。换句话说,我希望Peter拥有A
,B
和C
,但没有Jake,因为他只有A
和B
。
编辑:我不希望name
具有A,B和C,但我只想看看它们是否具有A
,B
和{ {1}}。因此,如果Peter拥有C
(示例中未包含),也很好。
我尝试过:
D
但这不会产生任何结果。
df[(df.Product == 'A') & (df.Product == 'B') & (df.Product == 'C')]
这只是连接行。
答案 0 :(得分:4)
如果要测试,每个组正好具有3个唯一的list值,则将boolean indexing
与set
的anf过滤器进行比较:
lst = list(['A','B','C'])
df = df[df.groupby('name')['product'].transform(lambda x: set(x) == set(lst))]
print (df)
name product
0 Peter A
1 Peter B
2 Peter C
如果需要列表的测试值以及其他任何值:
df= pd.DataFrame({
'name': ['Peter', 'Peter', 'Peter', 'Peter', 'Jake'],
'product' : ['A', 'B', 'C', 'D', 'B']
})
lst = list(['A','B','C'])
df = df[df.groupby('name')['product'].transform(lambda x: set(x) >= set(lst))]
print (df)
name product
0 Peter A
1 Peter B
2 Peter C
3 Peter D
答案 1 :(得分:3)
这是isin
和filter
的一种方式-但如果数据量大,速度会很慢:
df=df.groupby('Name').filter(lambda x : pd.Series(['A','B','C']).isin(x['Product']).all())
df
Name Product
0 Peter A
1 Peter B
2 Peter C
Jez的测试用例
df= pd.DataFrame({
'Name': ['Peter', 'Peter', 'Peter', 'Jake', 'Jake','Jake'],
'Product' : ['A', 'B', 'C', 'A', 'B','A']
})
df.groupby('Name').filter(lambda x : pd.Series(['A','B','C']).isin(x['Product']).all())
Name Product
0 Peter A
1 Peter B
2 Peter C
根据他提供的'Product' : ['A', 'A', 'C', 'A', 'B','A']
df.groupby('Name').filter(lambda x : pd.Series(['A','B','C']).isin(x['Product']).all())
Empty DataFrame
Columns: [Name, Product]
Index: []
答案 2 :(得分:2)
IIUC和给定名称应包含所有产品,您可以使用nunique
来计算唯一产品的数量。然后检查按name
进行分组的情况,该组中的唯一计数与整列中一样多:
prods = df['product'].nunique()
df[df.groupby('name')['product'].transform('nunique').eq(prods)]
name product
0 Peter A
1 Peter B
2 Peter C
答案 3 :(得分:0)
问题尚不清楚,我认为OP对所有产品A,B,C
感兴趣。然后一个人可以做:
s = (df.groupby('Name')['Product']
.transform(lambda x: x.value_counts()
[['A','B','C']].gt(0).all()
)
)
df[s]
输出:
Name Product
0 Peter A
1 Peter B
2 Peter C