是否有可能按列表过滤 pandas?
Is there any possibility to filter pandas by list?
我有一个包含列 product_id
和 keyword
的 df。我通过 group_name, group in s.groupby('product_id')
迭代产品 ID,在这一步中,我想保留包含搜索列表中所有元素的组。
例如:
我的搜索列表 = ['land', 'cruiser']
所以在输出中,我想要这个:
我试过了
data[data["keywords"].isin(search_words)]
但此方法保留所有组,如果它包含列表中的至少一个元素,而 I 组必须包含搜索列表中的所有元素。
对于不同的答案(在一行中!):
import pandas as pd
s = pd.DataFrame({'product_id': [1, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4],
'keywords': ["land", "cruiser", "land", "cruiser", "land",
"land", "land", "cruiser", "cruiser", "land", "cruiser"]})
search_words = ['land', 'cruiser']
s[[(all(p in x for p in search_words)) \
for x in s.merge(s.groupby("product_id").apply(
lambda x: list(set(x["keywords"]))).to_frame(). \
rename(columns={0: "grouped"}), left_on="product_id",
right_index=True)["grouped"]]]
#Out:
# product_id keywords
#0 1 land
#1 1 cruiser
#2 1 land
#3 1 cruiser
#4 1 land
#9 4 land
#10 4 cruiser
编辑
我刚刚使用了 pandas groupby filtration,并意识到在这里使用它会简单得多。返回的dataframe和上面的完全一样,只是代码少了很多!
s.groupby("product_id").filter(lambda x: all(p in list(set(x["keywords"])) for p in search_words))
这里的核心逻辑摘自。
我创建了一些辅助变量,而不是 one-liner——我创建了一系列 product_id 及其所有相关的搜索词 (product_keywords)。然后我制作了一个包含所有关键字的所有 product_id 的系列(守护者)。最后,我使用 isin() 方法测试数据帧行是否在该列表中有 product_id。
这会保留组中包含所有搜索词的所有词;因此,如果第 1 组有“land”和“cruiser”以及其他词,则这会包含所有术语。
df = pd.DataFrame({"product_id": [1,1, 2, 3, 1, 2, 3],
"keywords": ["land", "barn", "land", "land", "cruiser", "barn", "cruiser"]})
search_list = set(['land', 'cruiser'])
product_keywords = df.groupby("product_id").apply(lambda x: list(set(x["keywords"])))
product_keywords
# product_id
# 1 [barn, cruiser, land]
# 2 [barn, land]
# 3 [cruiser, land]
keepers = product_keywords[product_keywords.apply(lambda found_terms: all(search_term in found_terms for search_term in search_list))]
keepers
# product_id
# 1 [barn, cruiser, land]
# 3 [cruiser, land]
df.loc[df['product_id'].isin(keepers.index)]
# product_id keywords
# 0 1 land
# 1 1 barn
# 3 3 land
# 4 1 cruiser
# 6 3 cruiser
我有一个包含列 product_id
和 keyword
的 df。我通过 group_name, group in s.groupby('product_id')
迭代产品 ID,在这一步中,我想保留包含搜索列表中所有元素的组。
例如:
我的搜索列表 = ['land', 'cruiser']
所以在输出中,我想要这个:
我试过了
data[data["keywords"].isin(search_words)]
但此方法保留所有组,如果它包含列表中的至少一个元素,而 I 组必须包含搜索列表中的所有元素。
对于不同的答案(在一行中!):
import pandas as pd
s = pd.DataFrame({'product_id': [1, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4],
'keywords': ["land", "cruiser", "land", "cruiser", "land",
"land", "land", "cruiser", "cruiser", "land", "cruiser"]})
search_words = ['land', 'cruiser']
s[[(all(p in x for p in search_words)) \
for x in s.merge(s.groupby("product_id").apply(
lambda x: list(set(x["keywords"]))).to_frame(). \
rename(columns={0: "grouped"}), left_on="product_id",
right_index=True)["grouped"]]]
#Out:
# product_id keywords
#0 1 land
#1 1 cruiser
#2 1 land
#3 1 cruiser
#4 1 land
#9 4 land
#10 4 cruiser
编辑
我刚刚使用了 pandas groupby filtration,并意识到在这里使用它会简单得多。返回的dataframe和上面的完全一样,只是代码少了很多!
s.groupby("product_id").filter(lambda x: all(p in list(set(x["keywords"])) for p in search_words))
这里的核心逻辑摘自
我创建了一些辅助变量,而不是 one-liner——我创建了一系列 product_id 及其所有相关的搜索词 (product_keywords)。然后我制作了一个包含所有关键字的所有 product_id 的系列(守护者)。最后,我使用 isin() 方法测试数据帧行是否在该列表中有 product_id。
这会保留组中包含所有搜索词的所有词;因此,如果第 1 组有“land”和“cruiser”以及其他词,则这会包含所有术语。
df = pd.DataFrame({"product_id": [1,1, 2, 3, 1, 2, 3],
"keywords": ["land", "barn", "land", "land", "cruiser", "barn", "cruiser"]})
search_list = set(['land', 'cruiser'])
product_keywords = df.groupby("product_id").apply(lambda x: list(set(x["keywords"])))
product_keywords
# product_id
# 1 [barn, cruiser, land]
# 2 [barn, land]
# 3 [cruiser, land]
keepers = product_keywords[product_keywords.apply(lambda found_terms: all(search_term in found_terms for search_term in search_list))]
keepers
# product_id
# 1 [barn, cruiser, land]
# 3 [cruiser, land]
df.loc[df['product_id'].isin(keepers.index)]
# product_id keywords
# 0 1 land
# 1 1 barn
# 3 3 land
# 4 1 cruiser
# 6 3 cruiser