我有一个具有以下通用格式的数据集:
id,thing_criteria_field,place_criteria_field
1,thing_1,place_2
1,thing_3,place_2
1,thing_3,place_2
1,thing_7,place_1
2,thing_3,place_3
2,thing_7,place_2
2,thing_9,place_2
2,thing_4,place_5
3,thing_1,place_1
3,thing_2,place_6
3,thing_3,place_6
3,thing_4,place_6
我想要完成的是在一个组中应用两个 bool 条件,这些条件值可以分布在组内的多个记录/行中。如果存在这些条件,则不要从组中过滤任何记录。如果没有,则过滤掉该组的所有记录。
这是一个简化的示例。标准集是巨大的列表,这就是为什么我将它们与管道连接并使用 str.contains() 和 regex=True 而不是更简单的东西。
这是我到目前为止所想到的,但我认为我什至没有走在处理组内多行标准的可能性或在找到时返回所有标准的正确轨道上。
thing_criteria = (x.df['thing_criteria_field'].str.contains('thing_1|thing2|thing3', regex=True))
place_criteria = (x.df['place_criteria_field'].str.contains('place_1', regex=True))
df_result = df.groupby('id').filter(lambda x: (thing_criteria & place_criteria).all())
这是我尝试从示例数据集创建的结果集:
id,thing_criteria_field,place_criteria_field
1,thing_1,place_2
1,thing_3,place_2
1,thing_3,place_2
1,thing_7,place_1
3,thing_1,place_1
3,thing_2,place_6
3,thing_3,place_6
3,thing_4,place_6
如有任何建议,我们将不胜感激!
最佳答案
试试这个:
# Build a dataframe indicating whether each row meets
# each of the individual criterion
all_criteria = [thing_criteria, place_criteria]
cond = pd.DataFrame(all_criteria).T \
.assign(id=df['id'])
# Now group them by id and reduce the truth values
# .any(): test if any row in the group matches a single criterion
# .all(): test if all criteria are met in the group
match = cond.groupby('id').apply(lambda x: x.iloc[:, :-1].any().all())
ids = match[match].index
# Finally, get the ids that matches all criteria
df[df['id'].isin(ids)]
<小时/>
any().all()
的工作原理: 假设您有以下组:
thing_criteria_field place_criteria_field id
0 True False 1
1 False False 1
2 False False 1
3 False True 1
-------------------------------------------------
any: True True ==> all: True
thing_criteria_field place_criteria_field id
4 False False 2
5 False False 2
6 False False 2
7 False False 2
-------------------------------------------------
any: False False ==> all: False
关于Python Pandas : Apply Multi-Line Boolean Criteria Within Group?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58827408/