一列中在另一列中没有特定值的元素

  • 本文关键字:一列 元素 python pandas numpy
  • 更新时间 :
  • 英文 :


我有一个DataFrame,让我们假设如下:

df=pd.DataFrame({'person':['Sebastian','Sebastian','Sebastian', 'Maria', 'Maria', 'Maria', 'Achim','Achim','Achim'],'item':['house','garden','sink','sink','gold','house','stone','gold','wood']})

现在我想获得所有不拥有某种物品(例如黄金)的人的列表。我已经找到了实现它的方法,但我认为还有更好的方法。我就是这样做的:

allPersons=df['person'].unique()
personWithGold=df[df['item']=='gold']['person'].unique()
personWithoutGold=allPersons[~np.isin(allPersons,personWithGold)]

对如何改进代码有什么建议吗?我总觉得有一个很简单的单行解决方案。

按人员分组并进一步筛选:

no_gold = df.groupby('person').apply(lambda x: (x['item'].ne('gold')).all())
persons_no_gold = no_gold[no_gold].index.values

array(['Sebastian'], dtype=object)

使用pd.get_dummies和索引

你也可以使用pd.get_dummies和一些过滤来获得你需要的而不是使用pd.DataFrame.groupby

import pandas as pd
forbidden_item = 'gold'
pivot = pd.get_dummies(df.set_index('person')['item']).max(level=0)
result = pivot[pivot[forbidden_item]==0].index.tolist()
result
['Sebastian']

数据透视表是这样的,因此您可以使用它来处理更复杂的逻辑。

print(pivot)
garden  gold  house  sink  stone  wood
person                                           
Sebastian       1     0      1     1      0     0
Maria           0     1      1     1      0     0
Achim           0     1      0     0      1     1

可以在这里使用布尔索引+.drop_duplicates():

who_has_gold = df.loc[df.item.eq('gold'), 'person'].drop_duplicates()
persons_without_gold = df.loc[~df['person'].isin(who_has_gold), 'person'].drop_duplicates()
print(persons_without_gold)

打印:

0    Sebastian
Name: person, dtype: object

最新更新